1
/*===========================================================================
2
Copyright (C) 19994-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 Massachusetts Ave, Cambridge,
19
Correspondence 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
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
.AUTHOR K. Banse IPG-ESO Garching
32
.KEYWORDS ImageDisplay, cursor
33
.PURPOSE Read the position of the two cursors on the ImageDisplay
34
and get density of relevant pixel.
35
Store xworld, yworld + intensity of cursor in descriptor
36
or table or not at all
37
.ALGORITHM Use enabled cursor(s) and read screen pixels, get real pixels
38
and world coord when the ENTER button is pressed on the cursor
39
board. Exit by pressing ENTER with enabled cursor(s) off.
40
Max. no. of coords is read from CURSOR(1), if this maximum is
41
reached, we exit automatically!
42
The real pixels, world coordinates + intensity are written to
44
Total no. of coords. read is stored in OUTPUTI(1).
45
Screen pixels are written to CURSOR(1,...4) within CURPOS.
47
the following keywords are used:
49
DAZHOLD/I/1/14 cursor(s) enabled, cursor form(s),
50
split screen mode + other info
51
P1/C/1/15 OR optional descriptor name where world coordinates
52
+ pixel values should be stored
53
OR table name, if data should go to a table
54
OR ?, if data only to be displayed on terminal
55
P2/C/1/2 = A or ?, for appending values to descriptor
56
or table or creating new descriptor/table
57
= ID for using identifiers in tables
58
= NO[,start_no] for automatic numbering in tables
59
start_no an optional starting number
61
(1:1) = Y for putting cross on screen, else no
62
in case of P2 = ID or NO
63
(2:2) = Y for writing also the identifier into
65
(3:3) = Y or Z for on-demand or continuous polling
67
INPUTI/I/15/1 holds zoom factor, if we work with zoom window
68
OUTPUTR/R/10/10 gets real pix, wld coords + intens for each cursor
69
OUTPUTI/I/1/1 receives total no. of coordinates obtained
70
CURSOR/I/1/4 (1) holds max. no. of coords reading on input
71
(1,,,4) will be filled with last cursor pos.
73
.ENVIRONment MIDAS and IDI
74
#include <midas_def.h> Prototypes for MIDAS interfaces
75
#include <idinumd.h> Global variables for DISPLAY interfaces
77
.VERSIONS 1.00 940615 F77 -> C of COORD.FOR, RvH
80
------------------------------------------------------------*/
82
/* Define _POSIX_SOURCE to indicate that this is a POSIX program */
84
#define _POSIX_SOURCE 1
87
#include <midas_def.h>
106
static int ra_flag, tra_flag, cooco[2];
108
static char inframe[64];
109
static char infofile[] = "/tmp/get_cur.info";
111
extern int logview_init(), display_it(), WR_SCREEN();
117
/*++++++++++++++++++++++++++++++
118
.PURPOSE write cursor output in to descriptor
119
------------------------------*/
122
static void WR_DESCR(int *flag, char *frame, char *descr, int ncurs,
123
int circfl, float *xyinfoA, float *xyinfoB )
125
static void WR_DESCR(flag,frame,descr,ncurs,circfl,xyinfoA,xyinfoB)
127
int *flag, ncurs, circfl;
128
float *xyinfoA, *xyinfoB;
140
/* saved variables */
142
static int mxrec = 10,
143
felem, fid, indx, ncols, norec;
144
static float rbuff[60]; /* max. 2 * 3 * mxrec data points */
154
if ( circfl ) /* circle */
157
if ( xyinfoB[3] > 0.0 ) ncols ++; /* also Radius2 */
158
if ( xyinfoB[4] > 0.0 ) ncols ++; /* also Radius3 */
166
(void) SCKGETC( "P2", 1, 1, &actvals, output ); /* get output_option */
167
if ((*output == 'a') || (*output == 'A'))
168
felem = -1; /* append the data */
173
/* open frame to write in descriptor */
175
(void) SCFOPN( frame, D_R4_FORMAT, 0, F_IMA_TYPE, &fid );
179
/* Do the actual writing into the descriptor */
183
for (ii=0; ii<3; ii++) rbuff[indx++] = xyinfoA[ii+4];
188
rbuff[indx++] = xyinfoB[2];
189
if (ncols >= 5) rbuff[indx++] = xyinfoB[3];
190
if (ncols >= 6) rbuff[indx++] = xyinfoB[4];
194
for (ii=0; ii<3; ii++) rbuff[indx++] = xyinfoB[ii+4];
198
if ( ++norec == mxrec ) /* we buffer the output */
200
(void) SCDWRR(fid,descr,rbuff,felem,(ncols*norec),&unit);
206
if ( *flag == CLOSE )
209
(void) SCDWRR(fid,descr,rbuff,felem,(ncols*norec),&unit);
210
(void) SCFCLO( fid );
217
/*++++++++++++++++++++++++++++++
218
.PURPOSE write cursor output in to table
219
------------------------------*/
223
static void WR_TABLE( int *flag, char *table, int ncurs, int circfl,
224
float *xyinfoA, float *xyinfoB, char *labl )
226
static void WR_TABLE( flag, table, ncurs, circfl,
227
xyinfoA, xyinfoB, labl )
229
int *flag, ncurs, circfl;
230
float *xyinfoA, *xyinfoB;
235
int actvals, idum, tindx, m, begin, unit;
236
static int dim3_plane;
238
float rdum, rbuff[10];
243
char idstr[10], buff[24], cbuf[3][24], tbunit[20], output[84];
246
/* initialized variables */
248
static char *info_iden = "enter identifier (with cursor in display window!): ";
249
static char *tblabl[3][10] =
250
{ {"X_coord","Y_coord","Value","X_coordpix","Y_coordpix"," "," "," "," "},
251
{"Xstart","Ystart","Value1","Xend","Yend","Value2",
252
"Xstartpix","Ystartpix","Xendpix","Yendpix"},
253
{"X_coord","Y_coord","Value","Radius1","Radius2","Radius3",
254
"X_coordpix","Y_coordpix"," "," "} };
255
static char *zlabl[2] = {"Z_coord","Z_coordpix"};
259
static int col_id, col_nr, ap_flag = -1, no_flag = -1, id_flag = -1,
260
tid, ncols, nooff, napp, nrow, colref[10];
261
static char oldstr[10];
272
if ( ncurs == 2 ) /* 3,6 columns for 1,2 cursors */
274
if ( circfl ) /* circle */
278
for (ii=0; ii<4; ii++)
279
(void) strcpy(&tlabel[ii][0],tblabl[tindx][ii]);
281
if ( xyinfoB[3] > 0.0 )
283
ncols ++; /* also Radius2 */
284
(void) strcpy(&tlabel[idum++][0],tblabl[tindx][4]);
286
if ( xyinfoB[4] > 0.0 )
288
ncols ++; /* also Radius3 */
289
(void) strcpy(&tlabel[idum++][0],tblabl[tindx][5]);
291
(void) strcpy(&tlabel[idum++][0],tblabl[tindx][6]);
292
(void) strcpy(&tlabel[idum][0],tblabl[tindx][7]);
298
for (ii=0; ii<ncols; ii++)
299
(void) strcpy(&tlabel[ii][0],tblabl[tindx][ii]);
302
else /* single cursor */
307
for (ii=0; ii<ncols; ii++)
308
(void) strcpy(&tlabel[ii][0],tblabl[tindx][ii]);
311
if ((ra_flag == 1) && (tindx != 1)) /* not for rectangle yet... */
313
(void) strcpy(tlabel[0],"RA ");
314
(void) strcpy(tlabel[1],"DEC ");
319
/* Get character string with flags for "A"ppend, "ID"entifier or "NO" */
321
(void) SCKGETC("P2",1,12,&actvals,output); /* get output_option */
325
/* either create new table or append values to existing one */
328
m = (int) strlen(output);
329
for (ii=0; ii<3; ii++)
332
idum = CGN_EXTRSS(output,m,'+',&begin,&cbuf[ii][0],20);
333
if (cbuf[ii][0] == 'A') ap_flag = 1;
334
if (cbuf[ii][0] == 'I') id_flag = 1;
335
if (cbuf[ii][0] == 'N') no_flag = ii;
339
(void) SCDRDI(imno,"NAXIS",1,1,&actvals,&naxis,&unit,&m);
340
if (naxis > 2) /* test, if a cube is loaded */
342
dim3_plane = ZPLANE; /* frame z-pixel */
343
(void) SCDRDD(imno,"START",3,1,&actvals,&ddum,&unit,&m);
344
zplane = (float)ddum;
345
(void) SCDRDD(imno,"STEP",3,1,&actvals,&ddum,&unit,&m);
347
zplane += (dim3_plane-1) * rdum; /* world coords */
353
if (ap_flag == -1) /* create new table */
356
/* create a (ncols+10)*100 table to have enough space for later use */
358
(void) TCTINI(table,F_TRANS,F_O_MODE,ncols+10,100,&tid);
359
for (ii=0; ii<ncols; ii++)
361
(void) strcpy(buff,&tlabel[ii][0]);
362
if (CGN_INDEXS(buff,"Rad") > 0)
363
(void) strcpy(tbunit,"Pixels");
364
else if (*buff == 'V')
365
(void) strcpy(tbunit," ");
368
if (CGN_INDEXS(buff,"pix") > 0)
369
(void) strcpy(tbunit,"Frame Pixels");
371
(void) strcpy(tbunit,"World Coords");
373
if (tra_flag == 1) /* single cursor */
376
(void) TCCINI(tid,D_R4_FORMAT,1,"S11.6",tbunit,buff,colref+ii);
378
(void) TCCINI(tid,D_R4_FORMAT,1,"S13.6",tbunit,buff,colref+ii);
380
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii);
383
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii);
388
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","World Coords","Z_coord",
390
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","Frame Pixels","Z_coordpix",
394
if (no_flag != -1) /* handle optional number column */
397
(void) TCCINI(tid,D_I4_FORMAT,1,"I8"," ","No",&col_nr);
398
idum = CGN_INDEXC(&cbuf[no_flag][0],',');
401
actvals = CGN_CNVT(&cbuf[no_flag][idum+1],1,1,&nooff,&rdum,&ddum);
402
if ( actvals <= 0 ) nooff = 0;
404
if (id_flag != -1) /* ID + NO is not possible */
405
SCTPUT("ID and NO flag not o.k. - only NO: column supported.");
408
(void) TCCINI(tid,D_C_FORMAT,8,"a8"," ","Ident",&col_id);
415
else /* open existing table and search for the required columns */
417
(void) TCTOPN( table, F_IO_MODE, &tid );
418
for (ii=0; ii<ncols; ii++)
420
(void) strcpy(buff,&tlabel[ii][0]);
421
(void) TCLSER(tid,buff,colref+ii);
425
"Missing column (label = %s) in input table, will be created...",
429
(void) strcpy(tbunit,"Pixels ");
430
else if (*buff == 'V')
431
(void) strcpy(tbunit," ");
434
if (CGN_INDEXS(buff,"pix") > 0)
435
(void) strcpy(tbunit,"Frame Pixels");
437
(void) strcpy(tbunit,"World Coords");
439
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii);
446
(void) TCLSER(tid,zlabl[0],colref+ii);
448
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","World Coords","Z_coord",
451
(void) TCLSER(tid,zlabl[1],colref+ii);
453
(void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","Frame Pixels",
454
"Z_coordpix",colref+ii);
457
if (no_flag != -1) /* handle optional number column */
459
(void) TCLSER(tid,"No",&col_nr);
461
(void) TCCINI(tid,D_I4_FORMAT,1,"I8"," ","No",&col_nr);
463
idum = CGN_INDEXC(&cbuf[no_flag][0],',');
466
actvals = CGN_CNVT(&cbuf[no_flag][idum+1],1,1,&nooff,&rdum,&ddum);
467
if ( actvals <= 0 ) nooff = 0;
469
if (id_flag != -1) /* ID + NO is not possible */
470
SCTPUT("ID and NO flag not o.k. - only NO: column supported.");
474
(void) TCLSER(tid,"Ident",&col_id);
476
(void) TCCINI(tid,D_C_FORMAT,8,"a8"," ","Ident",&col_id);
479
/* We append after the last row in the table */
481
(void) TCIGET( tid, &idum, &nrow, &idum, &idum, &idum );
488
/* Do the actual writing in the table */
492
nrow++; /* write in a new row */
493
for (ii=0; ii<3; ii++)
494
rbuff[ii] = *(xyinfoA+4+ii);
495
if (tra_flag == 1) rbuff[0] /= 15.0;
499
rbuff[3] = *(xyinfoA+2);
500
rbuff[4] = *(xyinfoA+3);
501
(void) TCRWRR(tid,nrow,5,colref,rbuff);
505
if ( circfl ) /* circle */
507
rbuff[3] = *(xyinfoB+2);
509
rbuff[4] = *(xyinfoB+3);
511
rbuff[5] = *(xyinfoB+4);
513
rbuff[ncols-2] = *(xyinfoA+2);
514
rbuff[ncols-1] = *(xyinfoA+3);
515
(void) TCRWRR(tid,nrow,ncols,colref,rbuff);
519
for (ii=0; ii<3; ii++)
520
rbuff[3+ii] = *(xyinfoB+4+ii);
521
rbuff[6] = *(xyinfoA+2);
522
rbuff[7] = *(xyinfoA+3);
523
rbuff[8] = *(xyinfoB+2);
524
rbuff[9] = *(xyinfoB+3);
525
(void) TCRWRR(tid,nrow,10,colref,rbuff);
532
rbuff[1] = (float) dim3_plane;
533
(void) TCRWRR(tid,nrow,2,colref+ncols,rbuff);
536
/* handle optional number and ident column */
541
(void) TCRWRI(tid,nrow,1,&col_nr,&idum);
542
(void) sprintf(labl,"%-d",idum);
548
SCTDIS(info_iden,-1);
549
actvals = 8; /* max. number of characters */
550
Cgetstr(idstr,&actvals);
552
(void) strcpy(idstr,oldstr);
554
(void) strcpy(oldstr,idstr);
559
idum = napp + cooco[1];
560
sprintf(idstr,"ID%4.4d",idum);
562
(void) TCEWRC(tid,nrow,col_id,idstr);
563
(void) strcpy( labl, idstr );
571
(void) sprintf(output,"Created via GET/CURSOR with image: %s",inframe);
572
(void) SCDWRC(tid,"HISTORY",1,output,-1,80,&unit);
584
int actvals, circfl, color, coomax, forma, give_info, go_on, knul, noc,
585
statA, statB, trncur, usr_lev, xpos, ypos, zoomwn;
586
int store, dazhld[2], ibuff[5];
588
static int coords[4] = { -1, -1, -1, -1 }; /* initial position of cursor */
590
float xyinfoA[7], xyinfoB[7];
592
char draw[4], cursfl[8], labl[9], cbuff[61], outname[61], output[81];
593
char *info_usr = "switch cursor(s) on - next time we exit...";
595
int outflg = FALSE, /* output to standard output */
607
for (nr=0; nr<7; nr++)
609
xyinfoA[nr] = xyinfoB[nr] = 0.0;
613
/* initialize MIDAS and global display variables */
615
(void) SCSPRO("Coord");
619
CONCHA_C(QDSPNO,QOVCH,1,0); /* Clear overlay-channel if necessary */
622
/* get main control block for ImageDisplay + keyword DAZHOLD */
624
(void) SCKRDI( "DAZHOLD", 1, 2, &actvals, dazhld, &unit, &knul );
629
/* get cursor(s) involved */
631
(void) SCKRDI( "CURSOR", 1, 2, &actvals, ibuff, &unit, &knul );
635
if (dazhld[0] != 2) /* if last curs shape was for single cursor */
636
forma = 1; /* we default to rectangle */
638
circfl = TRUE; /* circular ROI */
642
noc = 0; /* no support for single cursor #1 ... */
643
if (dazhld[0] > 1) /* if last curs shape was for two cursors */
644
forma = 3; /* we default to open cross */
651
scrfl = CLOSE; /* No info given on standard output */
656
/* get marker flag for drawing cross (and identifier) */
658
(void) strcpy(cursfl,"Y Y ?C0"); /* default to NoZoomWindow */
659
(void) SCKGETC("P3",1,3,&actvals,draw);
662
if (cursfl[3] == 'Z') /* on-demand or continuous cursor read */
664
cursfl[1] = 'N'; /* no marks in continuous mode */
665
noc = 0; /* force to only one cursor ... */
666
circfl = FALSE; /* rectangular cursor */
667
coomax = 100000000; /* put it to 100 000 000 */
670
cursfl[1] = *draw; /* this is the mark flag for the cross */
673
/* Read keyword DAZIN,
674
it contains resp.: zoom factor and auxilary window dimensions */
676
(void) SCKRDI("DAZIN",1,5,&actvals,ibuff,&unit,&knul);
678
if ((zoomwn = *ibuff) <= 0) /* no zoom window */
679
trncur = noc; /* true cursor no. */
680
else /* zoom window */
682
if ((ibuff[1] == 0) || (ibuff[2] == 0))
683
SCETER( 31, "FATAL: invalid window_specs..." );
686
/* Ok, x,y dimension auxilary window not zero */
688
cursfl[4] = 'Z'; /* that indicates zooming */
693
if (! circfl) /* pass also cursor no. of zoom window */
695
else /* indicate, that it's a circle... */
699
noc = 0; /* force to single cursor in main window */
703
/* for novice users display help */
705
(void) SCKRDI( "ERROR", 2, 1,&actvals, &usr_lev, &unit, &knul );
708
/* start up parallel logviewer or `classical' terminal I/O */
712
infofile[0] = '\0'; /* no parallel display */
713
(void) logview_init(infofile);
717
(void) logview_init(infofile);
718
if ( usr_lev == 1 ) auxhelp( 0 );
722
/* init cursor(s) in main window */
726
color = 0; /* define cursor colour */
727
if ( forma == -1 ) forma = 1;
732
if ( forma == -1 ) forma = 3;
734
(void) SETCUR_C(QDSPNO,noc,forma,color,coords);
737
/* Set output flag and name of output table or descriptor */
739
(void) SCKGETC("P1",1,60,&actvals,outname);
741
outflg = JUST_OUTPUT;
746
idum = CGN_INDEXS(outname,",d");
747
if (idum < 0) idum = CGN_INDEXS(outname,",D");
752
outname[idum] = '\0';
757
(void) strcpy(cbuff,outname);
758
CGN_FRAME(cbuff,3,outname,0);
762
cooco[0] = 0; /* counter for cursor reading */
763
cooco[1] = 0; /* counter for data storing */
764
(void) strcpy(inframe," "); /* necessary for calls of GetCursor */
767
/* read cursor position(s) */
769
give_info = go_on = TRUE;
770
while ((go_on) && (*cooco < coomax))
773
GetCursor(cursfl,inframe,xyinfoA,&statA,xyinfoB,&statB);
775
if ((statA == -9) && (*cooco == 0))
776
goto Cursor_loop; /* first entry & no keybd-input */
778
if ( (trncur == 0 && statA == 0)
780
(trncur == 2 && statA == 0 && statB == 0) )
782
if ( give_info && *cooco == 0 )
786
(void) strcpy(inframe," ");
791
if (cursfl[3] != 'Z')
794
SCTDIS(output,-9); /* erase last line */
800
/* we got cursor input - increment counter */
804
(*cooco)++; /* increment cursor read counter */
808
double dd1[3], dd2[3];
810
(void) SCFOPN(inframe,D_OLD_FORMAT,0,F_IMA_TYPE,&imno);
811
kk = fp2wc(0,imno,dd1,dd2);
812
if (kk == 0) ra_flag = 1;
817
if ((cursfl[3] != 'Z') || (statA < 0))
820
if (outflg != JUST_OUTPUT) store = 1;
823
/* store info in keyword OUTPUTR[10,...,20] */
825
(void) SCKWRR("OUTPUTR",xyinfoA+2,10,5,&unit);
826
if (trncur == 2) (void) SCKWRR("OUTPUTR",xyinfoB+2,15,5,&unit);
829
if (outflg == TBL_OUTPUT) /* fill table */
830
WR_TABLE(&tblfl,outname,trncur,circfl,xyinfoA,xyinfoB,labl);
833
else if (outflg == DES_OUTPUT) /* fill descriptor */
834
WR_DESCR(&desfl,inframe,outname,trncur,circfl,xyinfoA,xyinfoB);
837
/* if desired, draw label or number in overlay plane */
840
{ /* move one char. to the right */
841
xpos = CGN_NINT( xyinfoA[0] ) + 9;
842
ypos = CGN_NINT( xyinfoA[1] );
843
if ( trncur == 2 ) ypos += 9;
845
(void) IIGTXT_C(QDSPNO,QOVCH,labl,xpos,ypos,0,0,255,0);
850
/* in all cases, display line with complete info */
852
WR_SCREEN(&scrfl,cursfl,trncur,circfl,ra_flag,xyinfoA,xyinfoB,labl);
855
labl[0] = '\0'; /* clear label + advance one line */
859
} /* end of the while-loop */
862
/* That's it folks... */
864
if (cooco[1] > 0) /* something was entered */
866
if ( outflg == TBL_OUTPUT )
869
WR_TABLE(&tblfl,outname,trncur,circfl,xyinfoA,xyinfoB,labl);
871
else if (outflg == DES_OUTPUT)
874
WR_DESCR(&desfl,inframe,outname,trncur,circfl,xyinfoA,xyinfoB);
877
ibuff[0] = CGN_NINT(xyinfoA[0]);
878
ibuff[1] = CGN_NINT(xyinfoA[1]);
879
ibuff[2] = CGN_NINT(xyinfoB[0]);
880
ibuff[3] = CGN_NINT(xyinfoB[1]);
883
else if (conly) /* if Cursor only, get coords any way */
884
(void) IICRCP_C(QDSPNO,-1,noc,ibuff,ibuff+1,ibuff+2);
887
(void) SCKWRI("CURSOR",ibuff,1,4,&unit);
890
/* Save no. of coordinates obtained for subsequent applications */
892
(void) SCKWRI("OUTPUTI",cooco+1,1,1,&unit);
894
if ( zoomwn > 0 ) /* reset cursor setup */
895
SETCUR_C(QDSPNO,trncur,dazhld[1],2,coords);
898
(void) display_it("EOF",0);
900
if ( cursfl[1] == 'Y') (void) Crefrovr(); /* refresh overlay */