1
/*===========================================================================
2
Copyright (C) 1995-2008 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 P.Grosbol ESO/IPG
32
.KEYWORDS FITS, check keyword, classify
33
.COMMENT classify a FITS keyword
34
.VERSION 1.0 1988-Dec-10 : Creation, PJG
35
.VERSION 1.1 1989-Feb-24 : Upgrade for B-tables, PJG
36
.VERSION 1.4 1989-Oct-17 : Convert real to int in KEYWORD, PJG
37
.VERSION 1.87 1990-Oct-24 : Introduce HIERARCH keywords, PJG
38
.VERSION 2.25 1991-Sep-23 : Add new field types for BINTALBE, PJG
39
.VERSION 2.35 1992-Aug-12 : Allow 1<PCOUNT for BINTABLE and UNKNOW, PJG
40
.VERSION 2.45 1993-Mar-16 : Change TMEND/EXPTIME processing, PJG
41
.VERSION 2.50 1993-Apr-01 : Move decoding of MIDAS descriptors, PJG
42
.VERSION 2.80 1993-Dec-13 : Disable SC error for descriptors, PJG
43
.VERSION 2.85 1994-Jan-11 : Check for zero length history, PJG
44
.VERSION 3.00 1995-Feb-16 : Force GCOUNT>0 for none RG-format, PJG
45
.VERSION 3.10 1996-Oct-22 : Change allowed char. and 'fitshkw' call, PJG
46
.VERSION 3.15 1996-Nov-22 : Change allowed char., PJG
49
---------------------------------------------------------------------*/
57
#include <midas_def.h>
65
static int mdcnt; /* MIDAS descriptor card count */
67
static int ext_NAXIS=0;
68
static double tmstart;
86
/* pk -> new keyword to identify,
87
ps -> stored keywords with specified meaning from KWDEF */
95
if (c != cc) return 0;
99
if ((cc != ' ') && (cc < '0' || '9' < cc)) return 0;
102
return 1; /* names match */
109
int fitsckw(int mfd , BFDEF * bfdef , int htype , KWORD * kw , char fmt ,
110
char hist, int *delt_flag, int Midas_flag)
112
int fitsckw(mfd,bfdef,htype,kw,fmt,hist,delt_flag,Midas_flag)
113
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
114
.PURPOSE classify and store FITS keyword
115
.RETURN keyword type - 0:END, -1:not found, -2:error
116
---------------------------------------------------------------------*/
117
int mfd; /* IN: MIDAS file descriptor */
118
BFDEF *bfdef; /* OUT: Basic FITS definitions */
119
int htype; /* IN: type of FITS header */
120
KWORD *kw; /* IN: keyword structure */
121
char fmt; /* IN: file format, No/Orig/Fp */
122
char hist; /* IN: history flag No/Crypt/Yes */
123
int *delt_flag; /* OUT: 1 if CDELT found, else 0 */
124
int Midas_flag; /* IN: Midas flag */
129
char c, *ps, *pc, line[80];
130
register char dfmt, ckw;
132
int ktype, n, m, i, err;
133
int kwdsize, unit[4];
136
int SCTMES(), hdr_tbl_M(), SCDHWL();
146
char *cptr, lastchar;
151
if (!kw->kw) return (-2);
153
kwd = bkw; ktype = -1; *delt_flag = 0;
154
kwdsize = sizeof(KWDEF);
157
printf("fitsckw: kw = %s\n",kw->kw);
163
if (strcmp(kw->kw,"HIERARCH") == 0)
165
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
168
else if (strcmp(kw->kw,"HISTORY ") == 0)
171
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
177
{ /* check if all blanks */
178
if (strcmp(kw->kw," ") == 0)
180
kwd += 11; /* point to COMMENT entry */
181
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
186
{ /* compare with basic keyword list */
187
kwd += 2; /* point to first entry after HISTORY */
190
if (ckw < kwd->kw[0]) break; /* kwd is alphabetically sorted! */
192
if (ckw == kwd->kw[0])
194
if (kwcmp(kw->kw,kwd->kw))
196
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
206
/* not found - check list for tables */
208
if ((htype != IMAGE) && (ckw == 'T'))
209
{ /* use 2nd char, all keywords start with 'T' */
212
kwd = tkw; /* go through table keywords */
215
if (ckw < kwd->kw[1]) break; /* kwd is alphabetically sorted! */
217
if (ckw == kwd->kw[1])
219
if (kwcmp(kw->kw,kwd->kw))
221
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
231
/* not found in any list */
234
ndkw.group = WDESC; ndkw.type = '\0';
235
ndkw.fmt = 'N'; ndkw.action = 0;
236
ndkw.idx = (kw->fmt=='C') ? -1 : 1;
237
ndkw.fac = 1.0; ndkw.unit = (char *) 0;
238
ndkw.desc = kw->kw; pc = kw->kw; /* convert to legal name */
241
*pc++ = (('A'<=c && c<='Z') || ('0'<=c && c<='9') ||
242
('a'<=c && c<='z') || c=='-' || c==' ')
250
if (kwd->group==WDESC && kwd->action==HIERARCH)
255
if (FCT.PARM[3] == 1) /* should we ignore ESO.xyz keywords? */
259
reto = fitshkw(kw,kwd,i);
263
(line,"Warning: hierachical keyword not known (retval = %d)",reto);
264
SCTMES(M_BLUE_COLOR,line);
273
case 'L' : kwd->type = 'L'; break;
274
case 'I' : kwd->type = 'I'; break;
277
case 'R' : kwd->type = 'D'; break;
280
case 'S' : kwd->type = 'S'; break;
284
if (kwd->group==WDESC && /* skip blank keyword cards */
285
kw->fmt=='C' && !(*kw->val.pc) && !(mds && mdcnt)) return 1;
288
if ((kw->fmt != dfmt) && (dfmt != 'H') && (dfmt != 'N') && (dfmt != '\0'))
290
if (fitstkw(kw,kwd->fmt))
291
{ /* convert data format */
292
(void) sprintf(line,"Warning: Inconsistent data types [%c-%c] for >%s< !",
293
kwd->fmt,kw->fmt,kw->kw);
294
SCTMES(M_BLUE_COLOR,line);
301
{ /* goto keyword group for action */
305
case BFCTL : /* basic FITS control */
306
if (kw->kno && bfdef->naxis<kw->kno && *(kw->kw)!='P')
308
sprintf(line,"Warning: keyword %s - axis-index > NAXIS (= %d)",kw->kw,bfdef->naxis);
309
SCTMES(M_BLUE_COLOR,line);
317
bfdef->bitpix = kw->val.i;
318
mds = 0; tmstart = -1.0;
324
bfdef->naxis = kw->val.i;
325
if ((htype==BFITS || htype==RGROUP || htype==IMAGE) && fmt!='N')
329
if (MIDAS_MXDIM < bfdef->naxis)
331
if (MXDIM < bfdef->naxis)
335
(void) sprintf(txt,"NAXIS = %d, Max. NAXIS (%d) exceeded!",
337
SCTMES(M_RED_COLOR,txt);
343
for (i=MIDAS_MXDIM; i<MXDIM; i++) /* init also the rest */
350
adef[i].ctype[0] = '\0';
352
ext_NAXIS = 1; /* set switch */
356
bfdef->crflag = 0; /* indicate no CROTA there */
360
if (htype==RGROUP) n--;
361
adef[n].naxis = kw->val.i;
366
if (htype==RGROUP) n--;
368
SCTPUT("superfluous CRVAL ... not stored");
370
adef[n].crval = kw->val.d[0];
374
if (htype==RGROUP) n--;
376
SCTPUT("superfluous CRPIX ... not stored");
378
adef[n].crpix = kw->val.d[0];
382
if (htype==RGROUP) n--;
384
SCTPUT("superfluous CDELT ... not stored");
386
adef[n].cdelt = kw->val.d[0];
391
if (htype==RGROUP) n--;
393
SCTPUT("superfluous CTYPE ... not stored");
396
pc = kw->val.pc; ps = adef[n].ctype; i = MXS;
397
while (--i && (*ps++ = *pc++)); *ps = '\0';
402
if (htype==RGROUP) n--;
404
SCTPUT("superfluous CROTA ... not stored");
408
adef[n].crota = kw->val.d[0];
413
bfdef->bscale = kw->val.d[0];
414
bfdef->sflag = bfdef->sflag || (bfdef->bscale != 1.0);
418
bfdef->bzero = kw->val.d[0];
419
bfdef->sflag = bfdef->sflag || (bfdef->bzero != 0.0);
423
pc = kw->val.pc; ps = bfdef->bunit; i = MXS;
424
while (--i && (*ps++ = *pc++)); *ps = '\0';
425
if (*bfdef->bunit == '\0')
427
memset((void *)bfdef->bunit,32,(size_t)16);
428
*(bfdef->bunit + 16) = '\0';
433
bfdef->blank = kw->val.i; bfdef->bflag = 1;
437
bfdef->pcount = kw->val.i;
439
if (htype==RGROUP && MXPAR<bfdef->pcount)
441
SCTPUT("Error: Max. PCOUNT exceeded!");
444
if (htype!=RGROUP && htype!=BTABLE && bfdef->pcount!=0)
445
SCTMES(M_BLUE_COLOR,"Warning: PCOUNT not zero");
449
bfdef->gcount = kw->val.i;
451
if (htype!=RGROUP && bfdef->gcount!=1)
455
SCTMES(M_BLUE_COLOR,"Warning: GCOUNT < 1, changed to 1");
459
SCTMES(M_BLUE_COLOR,"Warning: GCOUNT > 1");
464
pc = kw->val.pc; ps = pdef[n].ptype; i = MXS;
465
while (--i && (*ps++ = *pc++)); *ps = '\0';
469
pdef[n].pscal = kw->val.d[0];
473
pdef[n].pzero = kw->val.d[0];
477
pc = kw->val.pc; ps = bfdef->extname; i = MXS;
478
while (--i && (*ps++ = *pc++)); *ps = '\0';
481
{ /* cut off trailing blanks */
492
pc = kw->val.pc; ps = bfdef->ident; i = MXIDNT;
493
while (--i && (*ps++ = *pc++)); *ps = '\0';
494
if (*bfdef->ident == '\0')
496
memset((void *)bfdef->ident,32,(size_t)71);
497
*(bfdef->ident + 72) = '\0';
502
bfdef->extver = kw->val.i;
506
bfdef->extlevel = kw->val.i;
510
bfdef->xflag = kw->val.i;
514
if (!strncmp(kw->val.pc,"IMAGE",5))
515
bfdef->mtype = F_IMA_TYPE;
516
else if (!strncmp(kw->val.pc,"TABLE",5))
517
bfdef->mtype = F_TBL_TYPE;
518
else if (!strncmp(kw->val.pc,"FIT",3))
520
bfdef->mtype = F_FIT_TYPE;
526
bfdef->dmin = kw->val.d[0];
531
bfdef->dmax = kw->val.d[0];
540
SCTMES(M_BLUE_COLOR,"Warning: Undef. basic action");
542
break; /* end - case BFCTL */
546
if (kw->kno && bfdef->extd && txdef->tfields<kw->kno)
548
SCTMES(M_BLUE_COLOR,"Warning: column index larger than TFIELD");
556
bfdef->mtype = F_TBL_TYPE;
557
if (fmt!='N') bfdef->cflag = 0;
560
SCTMES(M_RED_COLOR,"Error: Max. TFIELDS exceeded");
564
txdef = hdr_tbl(kw->val.i);
567
m = hdr_tbl_M(bfdef,kw->val.i);
568
if (m != 0) return (-9);
570
txdef = (TXDEF *)bfdef->extd;
575
txdef->theap = kw->val.i;
578
fdef[n].tbcol = kw->val.i - 1;
581
pc = kw->val.pc; ps = fdef[n].tform; i = MXS;
582
while (--i && (*ps++ = *pc++)); if (i) *ps = '\0';
584
if (dcffmt(pc,&fdef[n].trepn,&c,&fdef[n].twdth,&fdef[n].tdfdd))
585
SCTMES(M_RED_COLOR,"Error: invalid FORTRAN format");
591
(void) sprintf(fdef[n].tform,"A%d",fdef[n].trepn*fdef[n].twdth);
594
fdef[n].tdfmt = (htype==ATABLE) ? 'I' : 'S';
595
(void) strcpy(fdef[n].tform,"I11");
599
(void) strcpy(fdef[n].tform,"E15.5");
603
(void) strcpy(fdef[n].tform,"E15.5");
607
(void) strcpy(fdef[n].tform,"E15.5");
611
(void) strcpy(fdef[n].tform,"I11");
615
(void) sprintf(fdef[n].tform,"A%d",fdef[n].trepn);
619
strcpy(fdef[n].tform,"I4");
623
strcpy(fdef[n].tform,"I4");
628
strcpy(fdef[n].tform,"E15.5");
633
strcpy(fdef[n].tform,"E15.5");
638
strcpy(fdef[n].tform,"I11");
641
fdef[n].tdfmt = '\0'; break;
646
pc = kw->val.pc; ps = fdef[n].ttype; i = MXS;
647
while (--i && (*ps++ = *pc++)); *ps = '\0';
650
pc = kw->val.pc; ps = fdef[n].tunit; i = MXS;
651
while (--i && (*ps++ = *pc++)); *ps = '\0';
654
fdef[n].tscal = kw->val.d[0];
655
if (fdef[n].tscal!=1.0) fdef[n].sflag = 1;
658
fdef[n].tzero = kw->val.d[0];
659
if (fdef[n].tzero!=0.0) fdef[n].sflag = 1;
662
if (htype==ATABLE && kw->fmt=='S')
665
pc = kw->val.pc; ps = fdef[n].tnull; i = MXS;
666
while (--i && (*ps++ = *pc++)); *ps = '\0';
668
else if (htype==BTABLE && kw->fmt=='I')
671
fdef[n].tnnul = kw->val.i;
675
pc = kw->val.pc; ps = fdef[n].tdisp; i = MXS;
676
while (--i && (*ps++ = *pc++)); *ps = '\0';
679
SCTMES(M_BLUE_COLOR,"Warning: Undefined table action");
681
break; /* end - case TXCTL */
684
case WDESC : /* store keyword in descriptor */
685
if (fmt=='N') break; /* skip if NO file option */
688
{ /* special actions */
690
kw->val.d[0] /= 3600;
691
tmstart = kw->val.d[0]; break;
697
kw->val.d[0] -= 3600*tmstart;
698
if (kw->val.d[0]<0.0) kw->val.d[0] += 86400.0;
703
if (text_open(kw->val.pc,WRITE))
705
(void) sprintf(line,"Warning: cannot create textfile <%s>",
707
SCTMES(M_BLUE_COLOR,line);
715
err = SCDRDD(mfd,"O_TIME",5,1,&i,&d,unit,&i);
718
d = 24.0*fmod(kw->val.d[0],1.0);
719
err = SCDWRD(mfd,"O_TIME",&d,5,1,unit);
724
if (bfdef->tflag && !strcmp(kw->kw,"COMMENT "))
729
if (hist=='N' && kwd->fmt=='C') break; /* skip HIST+COMM */
730
if (!(*kwd->desc)) break; /* no associated descriptor */
732
if (0<=mfd) /* MIDAS file exists */
733
{ /* check for MIDAS descriptors */
735
/* *** instead of: n = 1; i = 0; SCECNT("PUT",&n,&i,&i); *** */
736
eco = ERRO_CONT; elo = ERRO_LOG; edi = ERRO_DISP;
737
ERRO_CONT = 1; /* disable SC-error handling */
738
ERRO_LOG = ERRO_DISP = 0;
741
if (kwd->fmt=='C' && !strncmp(kw->kw,"HISTORY ",8))
745
if (strncmp(kw->val.pc,"ESO-DESCRIPTORS START",21) == 0)
748
ERRO_CONT = eco; ERRO_LOG = elo; ERRO_DISP = edi;
753
{ /* decode MIDAS descriptors */
754
if (strncmp(kw->val.pc,"ESO-DESCRIPTORS END",19) == 0)
758
err = fitsrmd(mfd,kw,&mdcnt);
759
if (err != ERR_NORMAL)
765
(void) sprintf(line,"bad ESO descriptor %s",badname);
766
SCTMES(M_BLUE_COLOR,line);
769
ERRO_CONT = eco; ERRO_LOG = elo; ERRO_DISP = edi;
775
{ /* save value in MIDAS desc. */
777
if (!kw->val.pc) break;
778
i = (int) strlen(kw->val.pc);
781
(void) strcat(kw->val.pc," \n");
788
if (i<72 || kw->val.pc[71]!='\\')
790
(void) strcat(kw->val.pc,"\n"); i++;
794
kw->val.pc[71] = '\0'; i = 72;
799
if (strcmp(kwd->desc,"CONTINUE") == 0)
800
mdb_cont(mfd,2,kwd->desc,kw->val.pc);
805
kk = (int)strlen(cptr) - 1; /* index of last char. */
806
lastchar = *(cptr+kk);
808
mdb_cont(mfd,1,kwd->desc,kw->val.pc);
811
if ((strcmp(kwd->desc,"HISTORY") != 0) &&
812
(strcmp(kwd->desc,"COMMENT") != 0))
813
err = xSCDHWC(mfd,kwd->desc,1,kw->val.pc,kwd->idx,
816
err = SCDHWC(mfd,kwd->desc,1,kw->val.pc,kwd->idx,
822
err = SCDHWL(mfd,kwd->desc,&kw->val.i,kwd->idx,
826
if (strncmp(kwd->desc,"O_",2) != 0)
827
err = xSCDHWI(mfd,kwd->desc,&kw->val.i,kwd->idx,
830
err = SCDHWI(mfd,kwd->desc,&kw->val.i,kwd->idx,
835
if (strncmp(kwd->desc,"O_",2) != 0)
836
err = xSCDHWR(mfd,kwd->desc,&f,kwd->idx,
839
err = SCDHWR(mfd,kwd->desc,&f,kwd->idx,
843
if (strncmp(kwd->desc,"O_",2) != 0)
844
err = xSCDHWD(mfd,kwd->desc,kw->val.d,kwd->idx,
847
err = SCDHWD(mfd,kwd->desc,kw->val.d,kwd->idx,
851
default : /* everything else is bad type... */
855
ERRO_CONT = eco; /* reset directly */
857
ERRO_DISP = edi; /* instead of SCECNT("PUT",...) */
862
(void) sprintf(line,"Warning: <%s> of invalid type - not stored",
865
(void) sprintf(line,"Warning: <%s> of type <%c> - not stored",
866
kwd->desc,kwd->type);
867
SCTMES(M_BLUE_COLOR,line);
872
mdb_put(kw,kwd); /* no MIDAS file - buffer KW */
873
break; /* end - case WDESC */
877
SCTMES(M_BLUE_COLOR,"Warning: Undefined keyword group");
881
if (!bfdef->cflag) /* check if data file can be created */
886
if (kwd->action==NAXIS && kw->kno==bfdef->naxis) bfdef->cflag = 1;
890
if ((bfdef->kwflag & 3) == 3) bfdef->cflag = 1;
894
for (i=0; i<txdef->tfields; i++)
895
n = n && 0<=fdef[i].tbcol && fdef[i].tdfmt;
896
bfdef->cflag = (n) ? 1 : 0;
900
for (i=0; i<txdef->tfields; i++) n = n && fdef[i].tdfmt;
901
bfdef->cflag = (n) ? 1 : 0;
916
int fitsXckw(int mfd , BFDEF * bfdef , int htype , KWORD * kw)
918
int fitsXckw(mfd,bfdef,htype,kw)
919
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
920
.PURPOSE classify and store FITS keyword
921
.RETURN keyword type - 0:END, -1:not found, -2:error
922
---------------------------------------------------------------------*/
923
int mfd; /* IN: MIDAS file descriptor */
924
BFDEF *bfdef; /* OUT: Basic FITS definitions */
925
int htype; /* IN: type of FITS header */
926
KWORD *kw; /* IN: keyword structure */
932
in this routine we have Midas_flag == -2
933
which means we just need some basic FITS keywords
934
all other keywords are ignored
944
int ktype, n, i, kwdsize;
956
printf("fitsXckw: kw = %s\n",kw->kw);
960
if (!kw->kw) return (-2);
962
kwd = bkw; ktype = -1;
963
kwdsize = sizeof(KWDEF);
967
if ((ckw == 'H') || (ckw == ' ')) return ktype;
969
/* compare with basic keyword list */
970
kwd += 2; /* point to first entry after HISTORY */
973
if (ckw < kwd->kw[0]) break; /* kwd is alphabetically sorted! */
975
if (ckw == kwd->kw[0])
977
if (kwcmp(kw->kw,kwd->kw))
979
memcpy((char *)&ndkw,(char *)kwd,(size_t)kwdsize);
986
return ktype; /* not found - so we don't have to care! */
994
if (kwd->group != BFCTL) return ktype;
997
ktype = 1; /* BFCTL: basic FITS control */
998
if (kw->kno && bfdef->naxis<kw->kno && *(kw->kw)!='P') return ktype;
1001
switch (kwd->action)
1004
bfdef->bitpix = kw->val.i;
1011
bfdef->naxis = kw->val.i;
1014
if (MIDAS_MXDIM < bfdef->naxis)
1016
if (MXDIM < bfdef->naxis)
1020
(void) sprintf(txt,"NAXIS = %d, Max. NAXIS (%d) exceeded!",
1022
SCTMES(M_RED_COLOR,txt);
1028
for (i=MIDAS_MXDIM; i<MXDIM; i++) /* init also the rest */
1031
adef[i].crval = 1.0;
1032
adef[i].crpix = 1.0;
1033
adef[i].cdelt = 1.0;
1034
adef[i].crota = 0.0;
1035
adef[i].ctype[0] = '\0';
1037
ext_NAXIS = 1; /* set switch */
1041
bfdef->crflag = 0; /* indicate no CROTA there */
1045
if (htype==RGROUP) n--;
1046
adef[n].naxis = kw->val.i;
1052
bfdef->bscale = kw->val.d[0];
1053
bfdef->sflag = bfdef->sflag || (bfdef->bscale != 1.0);
1057
bfdef->bzero = kw->val.d[0];
1058
bfdef->sflag = bfdef->sflag || (bfdef->bzero != 0.0);
1062
bfdef->pcount = kw->val.i;
1067
bfdef->gcount = kw->val.i;
1069
if (htype!=RGROUP && bfdef->gcount!=1)
1071
if (bfdef->gcount<1) bfdef->gcount = 1;
1076
pc = kw->val.pc; ps = pdef[n].ptype; i = MXS;
1077
while (--i && (*ps++ = *pc++)); *ps = '\0';
1081
pdef[n].pscal = kw->val.d[0];
1085
pdef[n].pzero = kw->val.d[0];