/* @(#)midfctb.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:23 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++ Module MIDFCTB +++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1994 European Southern Observatory .LANGUAGE C .IDENTIFICATION Module MIDFCTB.C .AUTHOR Klaus Banse .KEYWORDS Midas FITS utility routines. .ENVIRONMENT VMS and UNIX .COMMENTS holds the FITS input routines: MID_fitstest, MID_fitsin, MID_fitsrdm, MyPut .VERSION [1.00] 920312: creation 011130 last modif ------------------------------------------------------------------------*/ #include #include #include /* General data definitions */ #include /* General data definitions */ #include /* Basic FITS definitions */ #include /* Table Extension definitions */ #include /* computer specific constants */ #include #include #define DISK_REC 512 static char *dataout_ptr; /* used in MyPut */ static int dataout_outtyp; /* */ #ifdef __STDC__ int MID_fitstest(char *fname) #else int MID_fitstest(fname) char *fname; /* IN: name of input FITS file */ #endif { char work[168], *nampntr; int fidcount, fid, n, kpath, retstat; extern char DATA_PATH[328]; retstat = -1;kpath = 0; fidcount = 0; nampntr = fname; work[0] = '^'; open_file: if ((fid = dopen(nampntr,READ,'S',0)) < 0) /* try to open FITS file */ { if (fidcount < 4) { n = fidcount*80; (void) strncpy(work,&DATA_PATH[n],80); if (work[0] != '^') { work[80] = ' '; kpath = CGN_INDEXC(work,' '); (void) strcpy(&work[kpath],fname); /* use new path */ nampntr = work; fidcount ++; goto open_file; } } return retstat; } if (drinit() != FITS) /* check file format */ retstat = -2; else retstat = 0; dclose(fid); return retstat; } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .AUTHOR K. Banse ESO/IPG .KEYWORDS FITS prime data matrix, decode, read .PURPOSE Read prime data matrix in FITS and create a MIDAS bdf-file .ALGORITHM Either just read the FITS header to create a corresponding Midas header in memory Or just skip the FITS header to get to the data. .RETURN status 0: OK, -1: cannot open file, -2: wrong format -3: no data matrix, -4: bad output name -5: unknown FITS extension ---------------------------------------------------------------------*/ #ifdef __STDC__ int MID_fitsin(int flag, char *fname, char *extensio, char *bname, char *outbuf, int *mfd, int *info) #else int MID_fitsin(flag,fname,extensio,bname,outbuf,mfd,info) int flag; /* IN: option = -1, list all extensions (y) = 0, get type of FITSfile [extension] (x) = 1, get FITS header (a) = 2, get FITS data (b) = 3, skip FITS header (c) */ char *fname; /* IN: name of input FITS file */ char *extensio; /* IN: extension as string (a,x) */ char *bname; /* IN: name of output BDF file - only for (a) */ char *outbuf; /* IN/OUT: output buffer (a) return path name if applicable (b) pointer to data area to be filled (c,x,y) ignored */ int *mfd; /* IN/OUT: MIDAS file no. output (a), input (b,c) */ int *info; /* OUT: info = FITS file type (a,x) not used (b) fileid from dopen (c) no. of extensions (y) */ #endif { char work[168], *nampntr, extlabel[24], temp[128]; int Mflag, dsize, fidcount, fid, err, kpath, n, type, mfdt, imno; int extno, extcount, extrecs; float rdum; double ddum; BFDEF *bfdefptr, bfdef; ADEF *adefptr, adef[MXDIM]; PDEF *pdefptr, pdef[MXPAR]; struct FCT_STRUCT *fctpntr; extern char DATA_PATH[328]; kpath = 0; fidcount = 0; nampntr = fname; work[0] = '^'; open_file: if ((fid = dopen(nampntr,READ,'S',0)) < 0) /* try to open FITS file */ { if (fidcount < 4) { n = fidcount*80; (void) strncpy(work,&DATA_PATH[n],80); if (work[0] != '^') { work[80] = ' '; kpath = CGN_INDEXC(work,' '); (void) strcpy(&work[kpath],fname); /* use new path */ nampntr = work; fidcount ++; goto open_file; } } return (-1); } if (drinit() != FITS) /* check file format */ { /* if not FITS format - exit */ dclose(fid); return (-2); } /* if flag < 2 we have to get the FITS header in */ /* --------------------------------------------- */ if (flag < 2) /* process flag = -1, 0, 1 */ { int ec, ed, el, ln0, ln1; char *mypntr; *mfd = mfdt = -1; /* don't access data yet */ err = outname(bname,-1); if (err) { /* define output file name + check it */ dclose(fid); return (-4); } mypntr = malloc((unsigned int) (sizeof(bfdef))); if (mypntr == (char *) 0) return (-5); bfdefptr = (BFDEF *) mypntr; mypntr = malloc((unsigned int) (MXDIM*sizeof(adef))); if (mypntr == (char *) 0) return (-5); adefptr = (ADEF *) mypntr; mypntr = malloc((unsigned int) (MXPAR*sizeof(pdef))); if (mypntr == (char *) 0) return (-5); pdefptr = (PDEF *) mypntr; hdr_init_M(bfdefptr,&adefptr,&pdefptr,0); /* init internal structure */ extrecs = 0; /* read FITS header, create file (only if flag = 1) */ (void)SCECNT("GET",&ec,&el,&ed); ln0 = 0; ln1 = 1; (void)SCECNT("PUT",&ln1,&ln0,&ln0); if (flag == 1) Mflag = 1; else /* we just want info */ Mflag = -1; extcount = 0; /* for flag = -1, we just loop through all extensions */ if (flag == -1) { type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); if (type < BFITS) { (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-2); } CGN_FILL(work,' ',25); work[25] = '\0'; if (dsize < 1) /* an empty primary matrix, so look for next */ { (void) strcpy(extlabel,"Empty primary header"); (void) sprintf(temp,"extension[%d] %s - type = %s", extcount,work,extlabel); } else { if (type == ATABLE) (void) strcpy(extlabel,"Ascii table"); else if (type == BTABLE) (void) strcpy(extlabel,"Binary table"); else (void) strcpy(extlabel,"Image"); (void) sprintf(temp,"extension[%d] %s - type = %s", extcount,work,extlabel); } SCTPUT(temp); extcount ++; n_loop: (void) fitssxd(dsize,1); /* skip data matrix */ hdr_init_M(bfdefptr,&adefptr,&pdefptr,1); /* init again */ type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); if (type == EOFITS) { /* we reached EOF */ flag = 0; *info = extcount; /* save total no. of extensions */ goto after_exttypes; } else if (type < BFITS) { (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-2); } if (type == ATABLE) (void) strcpy(extlabel,"Ascii table"); else if (type == BTABLE) (void) strcpy(extlabel,"Binary table"); else if (type == IMAGE) { if (dsize < 1) /* an empty header */ (void) strcpy(extlabel,"Empty header"); else (void) strcpy(extlabel,"Image"); } else { if (dsize < 1) /* an empty header */ (void) strcpy(extlabel,"Empty header"); else (void) strcpy(extlabel,"? "); } CGN_FILL(work,' ',16); work[16] = '\0'; n = CGN_COPY(work,bfdefptr->extname); if (n < 16) work[n] = ' '; (void) sprintf(temp,"extension[%d] EXTNAME: %s - type = %s", extcount,work,extlabel); SCTPUT(temp); extcount ++; goto n_loop; } /* check, if we want an extension of the FITS file */ if (extensio[0] == '\0') /* No, frame without extension */ { type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); if (type < BFITS) /* main header */ { (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-2); } if (dsize > 0) /* basic FITS goes to IMAGE type */ *info = 1; else { /* search for first non-empty header */ while ( (dsize < 1) && ((type == BFITS) || (type == IMAGE)) ) { *mfd = -1; mfdt = -1; hdr_init_M(bfdefptr,&adefptr,&pdefptr,1); /* init again */ type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); if (type == EOFITS) { (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); /* only empty headers... */ return (-2); } } *info = 0; if (type == ATABLE) *info = 3; else if (type == BTABLE) *info = 2; else if (type == IMAGE) *info = 1; extcount ++; /* count extensions */ } extno = 0; /* ext.no. 0 = main frame */ goto after_exttypes; } /* Yes - we do have an extension */ if (Mflag == 1) Mflag += 100; /* mark possible empty file for `fitsrhd' */ extno = -1; if (CGN_CNVT(extensio,1,1,&extno,&rdum,&ddum) < 1) { extlabel[16] = '\0'; if (extensio[0] == '"') { for (n=0; n<16; n++) /* extensions have max. 16 chars */ { extlabel[n] = extensio[n+1]; if (extlabel[n] == '"') { extlabel[n] = '\0'; break; } } } else { for (n=0; n<16; n++) /* extensions have max. 16 chars */ { extlabel[n] = extensio[n]; if (extlabel[n] == ' ') { extlabel[n] = '\0'; break; } } } CGN_UPSTR(extlabel); } else { extlabel[0] = '\0'; /* indicate number */ if (extno < 0) { (void) sprintf(work,"Warning: Invalid FITS extension ( = %d)\n",extno); SCTPUT(work); (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-9); } } /* read very first FITS header */ type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); if (type < BFITS) /* main header */ { (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-2); } /* extension 0 has to be treated specially */ if (extno == 0) { *info = 1; /* always type IMAGE */ extno = -1; /* so it's recognized as an extension */ goto after_exttypes; } /* save type of header */ if (dsize < 1) /* empty primary header -> IMAGE */ *info = 1; else { *info = 0; if (type == ATABLE) *info = 3; else if (type == BTABLE) *info = 2; else if (type == IMAGE) *info = 1; } /* an extension cannot be the first header... so, we move on to next extension of FITS file */ extens_loop: if (dsize > 0) { ln0 = fitssxd(dsize,1); /* skip data matrix */ extrecs += ln0; } if ((Mflag != 0) && (*mfd > -1)) { /* clear previously created files */ if (*info == 1) (void) SCFCLO(*mfd); else if (*info > 1) (void) TCTCLO(*mfd); } *mfd = -1; mfdt = -1; hdr_init_M(bfdefptr,&adefptr,&pdefptr,1); /* init again */ type = fitsrhd(mfd,bfdefptr,&dsize,&mfdt,'O','Y',0,Mflag); extcount ++; if (type == EOFITS) { /* we reached EOF */ (void)SCECNT("PUT",&ec,&el,&ed); dclose(fid); return (-9); } /* save type of extensions */ *info = 0; /* = 0 is bad... */ if (type == ATABLE) *info = 3; else if (type == BTABLE) *info = 2; else if (type == IMAGE) *info = 1; else { if (dsize < 1) *info = 1; /* empty headers -> IMAGE */ } /* hunt down the required extension */ if (extlabel[0] != '\0') /* extension string */ { CGN_UPSTR(bfdefptr->extname); if (strcmp(extlabel,bfdefptr->extname) != 0) goto extens_loop; } else /* extension no. */ { if (extcount != extno) goto extens_loop; } /* here the main header + extensions (also ext. 0) join */ after_exttypes: (void)SCECNT("PUT",&ec,&el,&ed); if (type == UKNOWN) { (void) sprintf(temp,"Unknown FITS extension ( = %d)\n",extno); SCTPUT(temp); dclose(fid); return (-9); } /* if we just want to know the file type we can return now */ if (flag == 0) { TXDEF *tpntr; if (bfdefptr->extd != (char *) 0) { tpntr = (TXDEF *) bfdefptr->extd; free((char *)tpntr->col); free(bfdefptr->extd); } free((char *)bfdefptr); free((char *)adefptr); free((char *)pdefptr); dclose(fid); if (*mfd > -1) { fctpntr = FCT.ENTRIES + (*mfd); for (n=0; n<3; n++) fctpntr->FITSADDR[n] = (char *) 0; } return (0); } fctpntr = FCT.ENTRIES + (*mfd); fctpntr->KAUX[2] = 0; fctpntr->KAUX[3] = dsize; fctpntr->FITSEXT = extno; /* save extension no. */ bfdefptr->count += extrecs; /* add skipped records */ fctpntr->FITSADDR[0] = (char *) bfdefptr; fctpntr->FITSADDR[1] = (char *) adefptr; fctpntr->FITSADDR[2] = (char *) pdefptr; if (work[0] != '^') /* return the path name */ { work[kpath] = '\0'; (void) strcpy(outbuf,work); } else { *outbuf = '^'; *(outbuf+1) = '\0'; } dclose(fid); } /* if flag > 1 we have the FITS header already in memory */ /* ----------------------------------------------------- */ else { /* file header already in */ Mflag = 1; imno = *mfd; fctpntr = FCT.ENTRIES + imno; bfdefptr = (BFDEF *) fctpntr->FITSADDR[0]; if (flag == 2) { (void) fitsmove(bfdefptr); /* only position file pointer ... */ fctpntr->FITSOUT = 'X'; /* indicate that the data is in ... */ dataout_ptr = outbuf; /* now read the data */ dataout_outtyp = fctpntr->DATTYP; dsize = fctpntr->KAUX[3]; if (fctpntr->FILTYP == 1) /* IMAGE */ fitsrdm(imno,bfdefptr,dsize,mfdt,'O',Mflag); else { if (fctpntr->FILTYP == 2) /* BTABLE */ fitsrbt(imno,bfdefptr,dsize,Mflag); else /* ATABLE */ fitsrat(imno,bfdefptr,dsize,Mflag); fctpntr->KAUX[2] = 0; /* reset descr_changed_flag */ } dclose(fid); } else { switch (bfdefptr->bitpix) /* check original data format */ { case 8 : n = D_I1_FORMAT; break; case -16 : n = D_UI2_FORMAT; break; case 16 : n = D_I2_FORMAT; break; case 32 : n = D_I4_FORMAT; break; case -32 : n = D_R4_FORMAT; break; case -64 : n = D_R8_FORMAT; break; } if (n != fctpntr->FORMAT) /* data format changed => cannot copy */ { dclose(fid); fid = -99; } else (void) fitsmove(bfdefptr); /* only position file pointer ... */ *info = fid; /* return the file id of FITS file */ } } return (0); } /* */ #ifdef __STDC__ int fitsmove(BFDEF *bfdef) #else int fitsmove(bfdef) BFDEF *bfdef; #endif { char *pc; register int nr; for (nr=0; nrcount; nr++) dread(&pc,FITSLR); return 0; } /* */ #ifdef __STDC__ int MyPut(int kdfmt, int kfelem, int kdn, char *inbuf) #else int MyPut(kdfmt,kfelem,kdn,inbuf) int kdfmt, kfelem, kdn; char *inbuf; #endif /* kdfmt = 8 D_I1_FORMAT kdfmt = 16 D_I2_FORMAT kdfmt = -16 D_UI2_FORMAT kdfmt = 32 D_I4_FORMAT kdfmt = -32 D_R4_FORMAT kdfmt = -64 D_R8_FORMAT */ { int nbyte, intype, kk; char *opntr; kk = kfelem - 1; /* start in output buffer */ nbyte = get_byte(dataout_outtyp); /* no. bytes of output data format */ opntr = dataout_ptr + (kk*nbyte); if (kdfmt == 8) intype = D_I1_FORMAT; else if (kdfmt == 16) intype = D_I2_FORMAT; else if (kdfmt == -16) intype = D_UI2_FORMAT; else if (kdfmt == 32) intype = D_I4_FORMAT; else if (kdfmt == -32) intype = D_R4_FORMAT; else intype = D_R8_FORMAT; /* do the conversion or just copy data */ conv_pix(opntr,inbuf,dataout_outtyp,intype,kdn); return 0; }