1
/*===========================================================================
2
Copyright (C) 1995-2010 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
/*+++++++++++++++++++ MIDAS monitor routines PREPG +++++++++++++++++++++++++
30
.IDENTIFICATION Module PREPG
31
.AUTHOR K. Banse ESO - Garching
33
MIDAS monitor, algebraic expressions, polish notation
35
holds KEXP_CLEAN, KEXP_ATOM, KEXP_REDUCE, KEXP_CLASSIFY, KEXP_POLISH,
36
KEXP_STACK, KEXP_PUSH, KEXP_POP, KEXP_PEEP
39
.VERSION [1.00] 870724: built from FORTRAN version 2.50
42
-------------------------------------------------------------------------*/
57
int KEXP_CLEAN(instring,outstring,maxcnt,atom,latom)
59
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61
replace all scalars by 'S', all arrays by 'A', all 1-arg functions by 'P'
62
all 2-arg functions by 'Q', 3-arg functions by 'R'
63
finally truncate all operators to one character.
65
use routine KEXP_ATOM to extract the objects listed above
66
test for functions and arrays
67
everything else is considered a scalar, constant or keyword,
68
(unless it's a delimiter)
69
This is a modified version of EXP_CLEAN in express.for
71
no. of operands in expression, -1 if something wrong
72
---------------------------------------------------------------------*/
74
char *instring /* IN: input string */;
75
char *outstring /* OUT: "cleaned" output string */;
76
int maxcnt /* IN: max. no. of atoms */;
77
char *atom[] /* OUT: pointer array \
78
points to extracted operands in original form */;
79
int latom[] /* OUT: holds lengths of 'atom' */;
82
int mycount, ml, ii, minus_flag, oo;
97
KAUX.STR[ml++] = instring[nr++]; /* copy the '"' */
99
while ((ck = instring[nr++]) != '\0')
104
if (instring[nr] == '"')
105
KAUX.STR[ml++] = instring[nr++];
106
ck = instring[nr]; /* set `ck' back to current elem */
110
return (-1); /* we need closing '"' */
114
if (ck == '\0') break; /* loop finished */
117
if ((ck == '*') && (cm == '*'))
119
KAUX.STR[ml++] = '`';
122
else if ((ck == '+') && (cm == '-'))
124
KAUX.STR[ml++] = '-';
127
else if ((ck == '-') && (cm == '-'))
129
KAUX.STR[ml++] = '+';
132
else if ((ck == '/') && (cm == '/')) /* ckey//ckey */
134
KAUX.STR[ml++] = '+'; /* not looked at in COMPU ... */
137
else if (ck != ' ') /* everything esle, but skip spaces */
148
/* extract atoms from left to right */
151
if (mycount >= maxcnt) /* return with error if too many operands */
154
latom[mycount] = KEXP_ATOM(&KAUX.STR[ii],&delim,atom[mycount]);
159
outstring[oo++] = ')'; /* append closing parenthesis */
161
outstring[oo] = '\0'; /* finished */
167
/* in first pass the atom + delimiter is returned */
168
/* ------------------------------------------------*/
170
if (latom[mycount] != 0)
173
outstring[oo] = 'S'; /* it's a scalar keyword or constant */
176
outstring[oo] = 'A'; /* default to keyword array */
178
if (*(atom[mycount]+1) == '$') /* look for M$function */
180
CGN_UPSTR(atom[mycount]);
181
if (*atom[mycount] == 'M')
185
cp = atom[mycount] + 2;
186
if ( (strncmp(cp,"INDEX",5) == 0) ||
187
(strcmp(cp,"FILTYP") == 0) ||
188
(strcmp(cp,"STRCMP") == 0) ||
189
(strcmp(cp,"PARSE") == 0) )
190
outstring[oo] = 'Q'; /* 2-arg function */
192
else if (strcmp(cp,"REPLA") == 0)
193
outstring[oo] = 'R'; /* 3-arg function */
195
else if (strncmp(cp,"EXIST",5) == 0)
198
if ( (ck == 'D') || (ck == 'C') )
199
outstring[oo] = 'Q'; /* 2-arg function */
201
outstring[oo] = 'P'; /* 1-arg function */
204
else if ( (strcmp(cp,"VALUE") == 0) ||
205
(strcmp(cp,"TNULL") == 0) )
208
char *xp, *cpp, *cppp;
211
cpp = (char *) 0; /* init */
212
cp = &KAUX.STR[ii+8]; /* move to after M$VALUE( */
213
mm = CGN_INDEXC(cp,')');
214
if (mm < 1) return (-1);
216
/* this processing disables:
217
m$value(..m$func()..) or m$value(..a+b..)
218
but supports: `wild' file names */
220
xp = cp; /* test for the different options */
222
for (nr=0; nr<mm; nr++)
225
if (cb == '[') /* (image[...]) */
236
{ /* (table,column,row) */
241
if ((mycount+3) >= maxcnt) return(-1);
243
latom[mycount] = CGN_COPY(atom[mycount],cp);
245
latom[mycount] = CGN_COPY(atom[mycount],cpp);
247
latom[mycount] = CGN_COPY(atom[mycount],cppp);
250
(void)strcpy(&outstring[oo],"R(S,S,S)");
260
for (nr=0;;nr++) /* if (key()) */
261
{ /* avoid P(A(S)) ... */
267
mm ++; /* include last ')' */
274
latom[mycount] = CGN_COPY(atom[mycount],cp);
276
(void)strcpy(&outstring[oo],"P(S)");
282
for (nr=0;;nr++) /* if (frame,descr()) */
283
{ /* avoid Q(S,A(S)) ... */
291
} /* (frame,descr) */
295
if ((mycount+2) >= maxcnt) return(-1);
297
latom[mycount] = CGN_COPY(atom[mycount],cp);
299
latom[mycount] = CGN_COPY(atom[mycount],cpp);
301
(void)strcpy(&outstring[oo],"Q(S,S)");
305
ii += (9+mm); /* skip M$VALUE(...) */
310
outstring[oo] = 'P'; /* all other are 1-arg functions */
316
ii += latom[mycount++];
320
minus_flag = 0; /* reset flag */
321
outstring[oo++] = ')'; /* and append closing parenthesis */
326
/* in second pass the delimiter only is returned */
327
/* -----------------------------------------------*/
333
if ( (oo == 0) || /* test for unary minus sign */
334
(outstring[oo-1] == '(') ) /* or (- */
336
*atom[mycount] = '0'; /* if so, replace it by " 0 - " */
337
atom[mycount][1] = ' ';
338
latom[mycount++] = 1;
339
outstring[oo++] = 'S';
341
else if ( (outstring[oo-1] == '*') || (outstring[oo-1] == '/') )
343
outstring[oo] = '('; /* open parenthesis */
344
*atom[mycount] = '0'; /* if so, replace it by " 0 - " */
345
*(atom[mycount]+1) = ' ';
346
latom[mycount++] = 1;
347
outstring[++oo] = 'S';
349
minus_flag = 1; /* set minus flag, since ) still to be added */
353
else if (delim == '+')
355
if ( (oo == 0) || /* test for unary plus sign */
356
( (oo > 0) && (outstring[oo-1] == '(') ) )
358
ii ++ ; /* if so, ignore it */
363
outstring[oo++] = delim;
374
int KEXP_ATOM(input,delim,atom)
376
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
378
extract atoms and their delimiters from an arithmetic expression
380
straight forward, but watch out for ASCII constants "..." , they may contain
382
This is a modified version of module EXP_ATOM in express.for
385
---------------------------------------------------------------------*/
387
char *input /* IN: input string */;
388
char *delim /* OUT: delimiter of returned atom */;
389
char *atom /* OUT: extracted operand */;
392
int const_flag, ii, latm;
395
register char delm, cc;
397
static int nlimits = 7, klimits = 9;
398
static char limits[9] = {'\0','*','/','(',')',',','`','+','-'};
416
/* here is the simplified 1st execution of the main_loop below */
417
/* ----------------------------------------------------------- */
421
if (delm == '"') /* check for ASCII constants */
426
else if (delm == '[')
429
goto main_loop; /* raise flag to 2 */
432
for (nr=1; nr<klimits; nr++) /* we checked for '\0' already above */
434
if (delm == limits[nr])
449
/* check for ASCII constants */
455
const_flag = 1 - const_flag; /* 1 => 0 and 0 => 1 */
456
goto main_loop; /* skip following tests */
459
else if (delm == '[')
464
goto main_loop; /* raise flag to 2 */
467
else if (delm == ']')
472
goto main_loop; /* lower flag to 0 */
476
if (const_flag == 0) /* we're NOT inside constant */
478
/* first look for ddd.Eee numbers */
480
if ( (delm == '+') || (delm == '-') )
485
if ( (cc == 'E') || (cc == 'e') || (cc == 'D') || (cc == 'd') )
487
for (nr=0; nr<latm-1; nr++)
490
if ( (cc != '.') && ((cc < '0') || (cc > '9')) )
493
goto main_loop; /* we got such a number, continue... */
498
(void) memcpy(atom,input,(size_t)latm);
504
for (nr=0; nr<nlimits; nr++)
506
if (delm == limits[nr])
508
(void) memcpy(atom,input,(size_t)latm);
516
goto main_loop; /* no delimiter - loop more */
523
int KEXP_REDUCE(input,output,operation)
525
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
527
extract from a given polish expression the next binary subexpression
528
and reduce the expression accordingly (replace subexpression by result)
530
look for instances of 'S S op' or 'A S )' or 'P S )' or 'Q S S )'
532
A = array, P = 1 arg function, Q = 2 arg function, R = 3 arg function
533
This routine is a modified verrsion of EXP_REDUCE in express.for
535
int starting index of subexpression in input string
536
------------------------------------------------------------------------*/
538
char *input /* IN: input string (terminated by '\0') */;
539
char *output /* OUT: "reduced" output string */;
540
char *operation /* OUT: subexpression to execute next */;
550
kk = (int) strlen(input);
556
t0 = &input[p1]; t1 = t0 + 1; t2 = t0 + 2;
560
/* look for 1-arg functions or arrays: P S ) or A S ) */
562
if ( (cr == 'P') || (cr == 'A') )
563
{ /* for functions treat specially */
564
if ( (*t2 != ')') || (*t1 != 'S') )
571
/* look for 2-arg functions: Q S S ) */
575
if ( (*(t0+3) != ')') || (*t1 != 'S') || (*t2 != 'S') )
582
/* look for 3-arg functions: R S S S ) */
586
if ( (*(t0+4) != ')') ||
587
(*t1 != 'S') || (*t2 != 'S') || (*(t0+3) != 'S') )
594
/* look for operation: S S op */
596
if ( (cr != 'S') || (*t1 != 'S') ||
597
(*t2 == 'S') || (*t2 == 'A') ||
598
(*t2 == 'P') || (*t2 == 'Q') || (*t2 == 'R') )
602
sect_200: /* valid operation found */
604
(void) strncpy(output,input,(size_t)p1); /* copy 1. part */
606
if (cr == 'R') /* copy last part */
607
(void) strcpy(&output[p1+1],&input[p1+5]);
609
else if (cr == 'Q') /* copy last part */
610
(void) strcpy(&output[p1+1],&input[p1+4]);
614
(void) strcpy(&output[p1+1],&input[p1+3]);
615
*(t0+3) = ' '; /* make sure, we have no trailing stuff... */
619
/* replace the operation by result */
622
(void) strncpy(operation,t0,(size_t)5); /* copy task into operation */
626
sect_1000: /* no valid operation, move on */
627
if (++p1 < kk) goto loop;
637
int KEXP_CLASSIFY(char input, int *ipr, int *spr)
639
int KEXP_CLASSIFY(input,ipr,spr)
641
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
643
assign an input and a stack priority to each operation
645
straight forward, since priorities are fixed
646
This routine is a modified version of EXP_CLASSifY in express.for
649
2 for operator, +,-,... ,
650
3 for function or array, P,Q,R,A
651
---------------------------------------------------------------------*/
653
char input; /* IN: input operator or operand */
654
int *ipr; /* OUT: input priority */
655
int *spr; /* OUT: stack priority */
659
static int inpr[8] = {1,1,2,2,4,0,0,3}; /* input precedence */
660
static int stpr[8] = {1,1,2,2,0,4,0,3}; /* stack precedence */
663
static char oper[8] = {'+','-','*','/','(',')',',','`'};
670
return (1); /* scalar */
672
if ( (input == 'A') || (input == 'P') || (input == 'Q') || (input == 'R') )
673
return(3); /* function or array */
676
/* otherwise compare input with operators */
678
for (nr=0; nr<8; nr++)
680
if (input == oper[nr])
684
return (2); /* should be an operator... */
688
return (2); /* nothing of above */
695
int KEXP_POLISH(instring,outstring)
697
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
699
convert an expression in "normal" algebraic notation to polish reversed notat
701
use a stack to store temporary data
702
functions as P(A+B) will be converted to PAB+) to indicate range of function
704
status: return status
705
= 0, o.k., else trouble...
706
---------------------------------------------------------------------*/
708
char *instring /* IN: input string */;
709
char *outstring /* OUT: output string in polish reversed notation */;
713
int flag, inext, inpr, kk;
715
int stapr, srval, stval;
722
kk = (int) strlen(instring);
728
/* extract operators and operands from left to right */
731
if (inext > kk) goto pop_next; /* end of string reached */
733
nchar = instring[inext++];
734
type = KEXP_CLASSIFY(nchar,&inpr,&stapr); /* classify token */
737
if (type == 1) /* number/variable */
739
outstring[onext++] = nchar;
743
else if (type == 2) /* operator */
746
if (nchar == ')') /* if [nchar] = closing parenthese, unwind stack */
749
flag = KEXP_POP(&stval,&stop); /* pop from stack */
750
if (flag == -1) return (1); /* missing parentheses... */
753
goto loop_more; /* eliminate matching parentheses */
754
else if (stop == '[')
756
outstring[onext++] = nchar; /* write ')' for end-of-function */
761
outstring[onext++] = stop; /* store stack operator in output str */
766
else if (nchar == ',')
767
{ /* if nchar = closing comma, unwind stack till '[' */
769
flag = KEXP_PEEP(&stval,&stop); /* look at stack */
770
if (flag == -1) return (1); /* something missing */
773
goto loop_more; /* ok... */
776
flag = KEXP_POP(&srval,&stop); /* pop stack */
777
outstring[onext++] = stop; /* store stack operator in output str */
782
else /* all other characters here... */
784
flag = KEXP_PEEP(&stval,&stop); /* look what's on top of the stack */
785
if (flag == -1) /* if stack empty, */
787
(void) KEXP_PUSH(stapr,nchar); /* push on stack always */
791
else if (inpr > stval) /* if input precedence > stack value, */
793
(void) KEXP_PUSH(stapr,nchar); /* push stack precedence on stack */
798
flag = KEXP_POP(&stval,&stop);
799
outstring[onext++] = stop;
807
outstring[onext++] = nchar;
808
(void) KEXP_PUSH(0,'['); /* push '[' on stack to mark function start */
809
inext ++; /* skip following '(' ... */
814
pop_next: /* end of input string reached */
815
while (KEXP_POP(&stval,&stop) != (-1))
816
outstring[onext++] = stop;
818
outstring[onext] = '\0'; /* stack empty - we're done */
828
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
835
---------------------------------------------------------------------*/
838
STACK.PNTR = -1; /* pointer to top of stack */
839
STACK.OVF = 39; /* max. 40 operands on line of 80 characters... */
845
int KEXP_PUSH(int ival, char cval)
847
int KEXP_PUSH(ival,cval)
849
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
857
---------------------------------------------------------------------*/
859
int ival /* IN: integer value */;
860
char cval /* IN: char. value */;
864
if (STACK.PNTR >= STACK.OVF) return (1);
866
STACK.CA[++STACK.PNTR] = cval; /* stack o.k. */
867
STACK.IA[STACK.PNTR] = ival;
876
int KEXP_POP(ival,cval)
878
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
886
---------------------------------------------------------------------*/
888
int *ival /* OUT: integer value */;
889
char *cval /* OUT: char. value */;
892
if (STACK.PNTR < 0) return (-1);
894
*ival = STACK.IA[STACK.PNTR]; /* stack o.k. */
895
*cval = STACK.CA[STACK.PNTR--];
903
int KEXP_PEEP(ival,cval)
905
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
913
---------------------------------------------------------------------*/
915
int *ival /* OUT: integer value */;
916
char *cval /* OUT: char. value */;
919
if (STACK.PNTR < 0) return (-1);
921
*ival = STACK.IA[STACK.PNTR]; /* stack o.k. */
922
*cval = STACK.CA[STACK.PNTR];
934
int nval, nulo, unit, imnoa, pixdim, direc, linflag, dispflg, sav;
935
int k, mm, off, stat, px3, npix[3], sublo[3], subhi[3];
938
char cbuf[104], tbuf[80], auxstr[80], convstr[80], subs[3][32];
941
double dd1[3], dd2[3], dd3[6], dnul[12];
950
cr = TOKEN[3].STR[0]; /* check, if no output wanted */
952
if ((cr == 'N') || (cr == 'n'))
954
sav = KIWORDS[OFF_LOG+3]; /* save current settings */
955
KIWORDS[OFF_LOG+3] = 1;
964
(void) FRAMACC('O',TOKEN[1].STR,1,&imnoa); /* open frame */
971
npix[0] = npix[1] = npix[2] = 1;
972
(void) SCDRDI(imnoa,"NPIX",1,3,&nval,npix,&nulo,&unit);
974
linflag = fp2wc(0,imnoa,dd1,dd2); /* init + test, if `real' WCS */
977
for (nr=0; nr<3; nr++)
985
(void) strcpy(cbuf,TOKEN[2].STR); /* coord specs */
988
if ((cr == '@') || (cr == '>') || (cr == '<') || (cr == 'C'))
989
direc = 1; /* frame pixels entered */
991
{ /* world coords entered */
993
k = CGN_INDEXC(cbuf,',');
994
if (k > 0) /* at least 2 dim */
997
k = CGN_INDEXC(&cbuf[nr],',');
1002
if ((cr == '@') || (cr == '>') || (cr == '<') || (cr == 'C'))
1003
px3 = 1; /* we have a 3rd fpix index */
1010
/* world coords in, frame pixels out */
1012
if (direc == 0) /* world coords entered */
1014
stat = Convcoo(0,imnoa,cbuf,3,&pixdim,sublo,subhi);
1023
(void) SCDRDD(imnoa,"START",1,3,&nval,dd1,&nulo,&unit);
1024
(void) SCDRDD(imnoa,"STEP",1,3,&nval,dd2,&nulo,&unit);
1025
dd1[0] = dd1[2] + sublo[2]*dd2[2];
1026
(void) sprintf(tbuf,"%8.8g",dd1[0]);
1028
for (nr=0; nr<7; nr++) /* skip leading blanks */
1030
if (tbuf[nr] != ' ')
1036
(void) strcpy(&cbuf[mm],&tbuf[k]);
1038
(void) sprintf(auxstr,"world coords entered = %s",cbuf);
1041
for (nr=0; nr<pixdim; nr++) sublo[nr] ++;
1044
if (pixdim == 1) /* 1-dim frame */
1046
(void) CGN_CNVT(cbuf,4,1,subhi,rval,dd1);
1047
(void) sprintf(cbuf,"frame pixels = %d",sublo[0]);
1050
else if (pixdim == 2) /* 2-dim frame */
1055
(void) strcpy(convstr,cbuf); /* prepare string for CNVT */
1056
for (nr=0; nr<80; nr++) /* ':' -> ',' */
1058
if (convstr[nr] == ':')
1060
else if (convstr[nr] == '\0')
1064
k = CGN_INDEXC(cbuf,',');
1066
off = CGN_INDEXC(cbuf,':'); /* off > 0: sexa -> dec */
1067
(void) move_sxdc(off,1,cbuf,auxstr); /* RA */
1068
(void) sprintf(tbuf," or %s, ",auxstr);
1071
if (off > 0) /* RA, DEC input */
1072
(void) CGN_CNVT(convstr,4,6,subhi,rval,dd3);
1073
else /* decimal input */
1074
(void) CGN_CNVT(convstr,4,2,subhi,rval,dd1);
1077
(void) move_sxdc(off,0,&cbuf[k],auxstr); /* DEC */
1078
(void) strcat(tbuf,auxstr);
1081
if (off > 0) /* tbuf holds decimal wc */
1082
(void) CGN_CNVT(&tbuf[5],4,2,subhi,rval,dd1);
1083
else /* tbuf holds RA,DEC wc */
1085
(void) strcpy(convstr,&tbuf[5]); /* save string, : -> , */
1086
for (nr=0; nr<80; nr++)
1088
if (convstr[nr] == ':')
1090
else if (convstr[nr] == '\0')
1094
(void) CGN_CNVT(convstr,4,6,subhi,rval,dd3);
1097
(void) SCKWRD("OUTPUTD",dd1,1,3,&unit); /* save dec. coords */
1098
(void) SCKWRD("OUTPUTD",dd3,4,6,&unit); /* save hours,mins,secs */
1100
(void) sprintf(cbuf,"frame pixels = %d,%d",sublo[0],sublo[1]);
1103
else /* 3-dim frame */
1107
(void) strcpy(convstr,cbuf); /* prepare string for CNVT */
1108
for (nr=0; nr<80; nr++) /* ':' -> ',' */
1110
if (convstr[nr] == ':')
1112
else if (convstr[nr] == '\0')
1116
k = CGN_INDEXC(cbuf,',');
1118
off = CGN_INDEXC(cbuf,':'); /* off > 0: sexa -> dec */
1119
(void) move_sxdc(off,1,cbuf,auxstr); /* RA */
1120
(void) sprintf(tbuf," or %s, ",auxstr);
1123
if (off > 0) /* RA, DEC input */
1124
(void) CGN_CNVT(convstr,4,6,subhi,rval,dd3);
1125
else /* decimal input */
1126
(void) CGN_CNVT(convstr,4,2,subhi,rval,dd1);
1128
CGN_strcpy(cbuf,&cbuf[k]); /* move to y-, z- pixel */
1129
k = CGN_INDEXC(cbuf,',');
1131
(void) move_sxdc(off,0,cbuf,auxstr); /* DEC */
1132
(void) strcat(tbuf,auxstr);
1134
if (off > 0) /* tbuf: dec. wc */
1135
(void) CGN_CNVT(&tbuf[5],4,2,subhi,rval,dd1);
1136
else /* tbuf: RA,DEC wc */
1138
(void) strcpy(convstr,&tbuf[5]); /* save string, : -> , */
1139
for (nr=0; nr<80; nr++)
1141
if (convstr[nr] == ':')
1143
else if (convstr[nr] == '\0')
1147
(void) CGN_CNVT(convstr,4,6,subhi,rval,dd3);
1150
(void) strcat(tbuf,", ");
1152
(void) CGN_CNVT(&cbuf[k],4,1,subhi,rval,&dd1[2]);
1153
(void) strcat(tbuf,&cbuf[k]);
1156
(void) SCKWRD("OUTPUTD",dd3,4,6,&unit); /* save hours,mins,secs */
1159
(void) sprintf(cbuf,
1160
"frame pixels = %d,%d,%d",sublo[0],sublo[1],sublo[2]);
1161
(void) SCKWRD("OUTPUTD",dd1,1,3,&unit); /* save dec. wcoords */
1164
dd2[0] = (double) sublo[0]; /* store frame pixels */
1165
dd2[1] = (double) sublo[1];
1166
dd2[2] = (double) sublo[2];
1167
(void) SCKWRD("OUTPUTD",dd2,10,3,&unit);
1171
/* frame pixels in, world coords out */
1173
else /* pixel coords. entered */
1177
for (nr=0; nr<3; nr++)
1179
k = CGN_EXTRSS(cbuf,(int)strlen(cbuf),',',&off,subs[nr],30);
1186
for (nr=0; nr<pixdim; nr++)
1188
if (subs[nr][0] == '<')
1190
else if (subs[nr][0] == '>')
1191
dd1[nr] = (double) npix[nr];
1192
else if (subs[nr][0] == 'C')
1195
dd1[nr] = (double) k;
1197
else /* remains only "@" format */
1199
if (CGN_CNVT(&subs[nr][1],4,1,&nval,&rr,&dd1[nr]) != 1)
1207
sublo[0] = (int) dd1[0]; /* split according to NAXIS */
1209
(void) sprintf(auxstr,"frame pixel entered = %d",sublo[0]);
1211
else if (pixdim == 2)
1213
sublo[1] = (int) dd1[1];
1214
(void) sprintf(auxstr,"frame pixels entered = %d,%d",sublo[0],sublo[1]);
1218
sublo[1] = (int) dd1[1];
1219
sublo[2] = (int) dd1[2];
1220
(void) sprintf(auxstr,"frame pixels entered = %d,%d,%d",sublo[0],sublo[1], sublo[2]);
1223
(void) SCKWRD("OUTPUTD",dd1,10,3,&unit); /* save frame pixels */
1225
if (fp2wc(1,imnoa,dd1,dd2) != 0) /* convert fp -> wc */
1231
/* split according to NAXIS */
1234
(void) sprintf(cbuf,"world coords = %10.8g",dd2[0]);
1236
else if (pixdim == 2)
1240
form_sexa(1,dd2[0],auxstr); /* RA */
1241
(void) strcpy(convstr,auxstr);
1242
for (nr=0; nr<80; nr++)
1244
if (convstr[nr] == ':')
1246
else if (convstr[nr] == '\0')
1249
(void) CGN_CNVT(convstr,4,3,subhi,rval,dd3);
1250
(void) SCKWRD("OUTPUTD",dd3,4,3,&unit);
1251
(void) sprintf(cbuf,"world coords = %10.8g, %10.8g or %s, ",
1252
dd2[0],dd2[1],auxstr);
1254
form_sexa(0,dd2[1],auxstr); /* DEC */
1255
(void) strcpy(convstr,auxstr);
1256
for (nr=0; nr<80; nr++)
1258
if (convstr[nr] == ':')
1260
else if (convstr[nr] == '\0')
1263
(void) CGN_CNVT(convstr,4,3,subhi,rval,dd3);
1264
(void) SCKWRD("OUTPUTD",dd3,7,3,&unit);
1265
(void) strcat(cbuf,auxstr);
1268
(void) sprintf(cbuf,"world coords = %10.8g,%10.8g",dd2[0],dd2[1]);
1274
form_sexa(1,dd2[0],auxstr); /* RA */
1275
(void) strcpy(convstr,auxstr);
1276
for (nr=0; nr<80; nr++)
1278
if (convstr[nr] == ':')
1280
else if (convstr[nr] == '\0')
1283
(void) CGN_CNVT(convstr,4,3,subhi,rval,dd3);
1284
(void) SCKWRD("OUTPUTD",dd3,4,3,&unit);
1285
(void) sprintf(cbuf,"world coords = %10.8g, %10.8g, %10.8g",
1286
dd2[0],dd2[1],dd2[2]);
1289
(void) sprintf(cbuf," or %s, ",auxstr);
1290
form_sexa(0,dd2[1],auxstr); /* DEC */
1291
(void) strcpy(convstr,auxstr);
1292
for (nr=0; nr<80; nr++)
1294
if (convstr[nr] == ':')
1296
else if (convstr[nr] == '\0')
1299
(void) CGN_CNVT(convstr,4,3,subhi,rval,dd3);
1300
(void) SCKWRD("OUTPUTD",dd3,7,3,&unit);
1301
(void) strcat(cbuf,auxstr);
1302
(void) sprintf(auxstr,", %10.8g",dd2[2]);
1303
(void) strcat(cbuf,auxstr);
1306
(void) sprintf(cbuf,"world coords = %10.8g, %10.8g, %10.8g",
1307
dd2[0],dd2[1],dd2[2]);
1310
(void) SCKWRD("OUTPUTD",dd2,1,3,&unit); /* save dec. wc */
1317
if (dispflg == -1) KIWORDS[OFF_LOG+3] = sav; /* reset LOG(4) */
1319
{ /* OUTPUTD(10-12) <- (-1) */
1323
SCTMES(M_RED_COLOR,"could not access given frame...");
1325
SCTMES(M_RED_COLOR,"CONVERT/COORDS: conversion failed...");
1327
for (nr=0; nr<3; nr++) dnul[nr] = -1.0;
1328
(void) SCKWRD("OUTPUTD",dnul,10,3,&unit);