# include # include # include # include /* for isspace */ # include /* for clear_cvoserr */ # include # include # define MIN_WAVELENGTH (2000.) # define N_AIR (1.0002735182) # define CONST1 (131.4182 ) # define CONST2 (2.76249e8) # define STIS_FNAME 255 static int FileExists (char *); static int CopyFile (char *, char *); static int ProcessOneTable (char *, int, int, int *); # if defined (NATIVE_IRAF) IRAFTASK(ovac2air) { # else int main (int argc, char **argv) { # endif char *infile; /* input file name */ char *outfile; /* output file name */ int count; int done; int verbose = 1; int inplace; int i; c_irafinit (argc, argv); infile = calloc (STIS_FNAME+1, sizeof (char)); outfile = calloc (STIS_FNAME+1, sizeof (char)); if (infile == NULL || outfile == NULL) { printf ("ERROR: Out of memory.\n"); # if defined (NATIVE_IRAF) return; # else exit (1); # endif } # if defined (NATIVE_IRAF) c_clgstr ("input", infile, STIS_FNAME); c_clgstr ("output", outfile, STIS_FNAME); inplace = 1; for (i = 0; i < strlen (outfile); i++) { if (!isspace(outfile[i])) { inplace = 0; break; } } # else if (argc == 2) { strcpy (infile, argv[1]); inplace = 1; } else if (argc == 3) { strcpy (infile, argv[1]); strcpy (outfile, argv[2]); inplace = 0; } else { printf ("syntax: xx_ovac2air.e input \n"); exit (1); } # endif if (inplace) { strcpy (outfile, infile); if (verbose) printf ("File %s will be processed in-place ...\n", outfile); } else { /* both input and output specified */ /* Make sure the output file does not already exist. */ if (FileExists (outfile)) { printf ("ERROR: Output file %s already exists.\n", outfile); # if defined (NATIVE_IRAF) return; # else exit (1); # endif } /* Copy infile to outfile. */ if (CopyFile (infile, outfile)) # if defined (NATIVE_IRAF) return; # else exit (1); # endif if (verbose) printf ("File %s copied to %s ...\n", infile, outfile); } /* Process each table in outfile. */ count = 1; done = 0; while (!done) { if (ProcessOneTable (outfile, count, verbose, &done)) break; count++; } free (outfile); free (infile); # if defined (NATIVE_IRAF) return; # else exit (0); # endif } /* This function returns 1 if the file exists and 0 if it does not exist. */ static int FileExists (char *outfile) { /* argument: char *outfile i: name of file */ FILE *ifp; if ((ifp = fopen (outfile, "r")) == NULL) { return (0); } else { fclose (ifp); return (1); } } # define FITS_BUFSIZE 2880 /* size of a FITS block */ /* This routine copies a file. */ static int CopyFile (char *infile, char *outfile) { /* arguments: char *infile i: name of input file char *outfile i: name of output file */ FILE *ifp, *ofp; /* for input and output files */ void *buf; /* buffer for copying blocks */ int nin, nout; /* number read and written */ int done; if ((buf = calloc (FITS_BUFSIZE, sizeof(char))) == NULL) return (1003); if ((ofp = fopen (outfile, "wb")) == NULL) { printf ("ERROR Can't create temporary file %s.\n", outfile); free (buf); return (1021); } if ((ifp = fopen (infile, "rb")) == NULL) { printf ("ERROR Can't open %s.\n", infile); fclose (ofp); remove (outfile); free (buf); return (1005); } done = 0; while (!done) { nin = fread (buf, sizeof(char), FITS_BUFSIZE, ifp); if (ferror (ifp)) { printf ("ERROR Can't read from %s (copying to %s).\n", infile, outfile); fclose (ofp); fclose (ifp); free (buf); return (1023); } if (feof (ifp)) done = 1; nout = fwrite (buf, sizeof(char), nin, ofp); if (nout < nin) { printf ("ERROR Can't copy %s to %s.\n", infile, outfile); fclose (ofp); fclose (ifp); free (buf); return (1025); } } fclose (ofp); fclose (ifp); free (buf); return (0); } static int ProcessOneTable (char *outfile, int count, int verbose, int *done) { char *outtable; /* output table name */ IRAFPointer tp; IRAFPointer cp; int nrows, row; /* number of rows, loop index */ int nelem; /* number of elements in wavelength array */ double *wl; /* array of wavelengths */ double wl2; /* wavelength squared */ int i; /* loop index */ int modified; /* true if any wavelength actually changed */ if ((outtable = calloc (STIS_FNAME+1, sizeof (char))) == NULL) { printf ("ERROR: Out of memory.\n"); return (1); } /* If count is one, don't append and extension number to the file name. This lets us work on stsdas tables as well as FITS tables. */ if (count == 1) strcpy (outtable, outfile); else sprintf (outtable, "%s[%d]", outfile, count); tp = c_tbtopn (outtable, IRAF_READ_WRITE, 0); if (c_iraferr()) { if (count == 1) { printf ("ERROR: Can't open table %s.\n", outtable); return (1); } /* else assume we've reached the end of file */ clear_cvoserr(); *done = 1; return (0); } c_tbcfnd1 (tp, "WAVELENGTH", &cp); if (cp == 0) { printf ("ERROR: Column WAVELENGTH not found in %s\n", outtable); return (1); } nrows = c_tbpsta (tp, TBL_NROWS); nelem = c_tbcigi (cp, TBL_COL_LENDATA); if ((wl = calloc (nelem, sizeof (double))) == NULL) { printf ("ERROR: Out of memory (%d elements).\n", nelem); return (1); } modified = 0; /* initial value */ for (row = 1; row <= nrows; row++) { if (c_tbagtd (tp, cp, row, wl, 1, nelem) < nelem) { printf ("ERROR: Couldn't get all %d elements from row %d\n", nelem, row); return (1); } if (c_iraferr()) { printf ("ERROR: Couldn't get wavelengths from row %d\n", row); return (1); } for (i = 0; i < nelem; i++) { if (wl[i] > MIN_WAVELENGTH) { wl2 = wl[i] * wl[i]; wl[i] /= (N_AIR + CONST1 / wl2 + CONST2 / (wl2 * wl2)); modified = 1; } } c_tbaptd (tp, cp, row, wl, 1, nelem); if (c_iraferr()) { printf ("ERROR: Couldn't put wavelengths back into row %d\n", row); return (1); } } if (modified) { c_tbhadt (tp,"HISTORY", "Wavelengths converted from vacuum to air."); if (verbose) { c_tbtnam (tp, outtable, STIS_FNAME); printf (" table %s updated.\n", outtable); } } else { printf ("Note: No change was made to %s;\n", outtable); printf (" all wavelengths were too short.\n"); } if (c_tbpsta (tp, TBL_WHTYPE) != TBL_TYPE_FITS) *done = 1; c_tbtclo (tp); free (wl); free (outtable); return (0); }