/* C program that analyzes STIS Target Acquisition. */ /* It makes use of the the imio.h functions. */ /* Written by R. Katsanis & R. Downes, 17-February-1998 */ /* Based on the original IDL code to analize target */ /* acquisition 'stis_ta.pro' written by George Hartig. */ /* 10-March-98: currently reads both the raw and the spt */ /* files. */ /* Changes made by Phil Hodge, 21-April-2000: 1. Read PEDESTAL from the primary header of the raw file instead of from the data portion of the spt extension. This solves the problem of negative pedestal values. 2. If at least one of the acquisitions did not succeed, then print a message to stderr (if compiled as a host program) or set acq_success in the parameter file to no (if compiled as a native IRAF task). 3. Compare the flux in the confirmation image with 0.9 times the maximum in the ACQ/PEAK scan. The messages printed to the standard output have been changed to mention this factor as "90%". 4. Move the "# include" statements from tastis.h to tastis.c. 5. Replace the nearest-integer macro. 6. Move calls to c_imunmap for imraw7 and imspt1 to the sections where the images were opened. Also call imunmap separately for the spt primary header. 7. Add FATAL_ERROR macro for out of memory, and use this value as an exit code if there was an error. 8. Initialize domfgs and subfgs strings to null. 9. Split the test on the quad filter (for setting the filter shift offset) into four separate tests. */ # include # include # include # include # include # include # include # include "tastis.h" # define FATAL_ERROR 2 # define FLUX_CUTOFF (0.9) static int TargetAcqAnalysis (char *, int *); static void ReadKeywords (IRAFPointer, IRAFPointer, IRAFPointer, IRAFPointer, imageinfo *); static void CalculateSlews (imageinfo *); static void PrintOutput (imageinfo *, int *); static double arcseconds (double); static double V2coord (double,double); static double V3coord (double,double); static void PrintWarnings (imageinfo *, int *); static void WriteError (int, char *); static int tastis_immap (char *, char *, IRAFPointer *); # if defined (NATIVE_IRAF) IRAFTASK(tastis) { # else int main (int argc, char **argv) { # endif int i; char input[IRAF_SZ_LINE]; /* list of input files */ IRAFPointer imlist; char infile[SZ_FNAME]; /* one input image name */ int nfiles; /* total number of input files */ int acqstatus; int status; c_irafinit (argc, argv); acqstatus = 0; /* initial values */ imlist = 0; # if defined (NATIVE_IRAF) c_clgstr ("input", input, IRAF_SZ_LINE-1); imlist = c_imtopen (input); nfiles = c_imtlen (imlist); if (nfiles < 1) { printf ("Null input, or no file matches input template.\n"); return; } # else if ( argc < 2 ) { printf ("syntax: tastis file1 file2 ...\n"); exit (FATAL_ERROR); } /* Allow either '*raw.fits' or 'file1 file2 ...' */ if (argc == 2) { imlist = c_imtopen (argv[1]); nfiles = c_imtlen (imlist); } else { nfiles = argc - 1; } if (nfiles < 1) { printf ("Null input, or no file matches input template.\n"); exit (FATAL_ERROR); } # endif /* Analyze each datafile that was listed on the command line. */ /* Loop over all input files. */ # if defined (NATIVE_IRAF) for (i=1; i<=nfiles; i++) { if (c_imtgetim (imlist, infile, SZ_FNAME-1) < 1) { printf ("Error parsing input string `%s'\n", input); return; } if (status = TargetAcqAnalysis (infile, &acqstatus)) { WriteError (status, infile); if (status == FATAL_ERROR) /* fatal error */ return; continue; } } # else for (i=1; i<=nfiles; i++) { if (imlist > 0) { if (c_imtgetim (imlist, infile, SZ_FNAME-1) < 1) { printf ("Error parsing input string `%s'\n", argv[1]); exit (FATAL_ERROR); } } else { strcpy (infile, argv[i]); } if (status = TargetAcqAnalysis (infile, &acqstatus)) { WriteError (status, infile); if (status == FATAL_ERROR) /* fatal error */ exit (FATAL_ERROR); continue; } } # endif if (imlist > 0) c_imtclose (imlist); # if defined (NATIVE_IRAF) /* Set a flag in the par file. This will be yes if every ACQ and ACQ/PEAK was OK, and it will be no if any appeared to be bad. */ if (acqstatus == 0) c_clputb ("acq_success", 1); else c_clputb ("acq_success", 0); # else if (acqstatus != 0) { if (nfiles == 1) fprintf (stderr, "It appears that the acquisition did not succeed.\n"); else fprintf (stderr, "It appears that at least one of the acquisitions did not succeed.\n"); } exit (acqstatus); # endif } static int TargetAcqAnalysis (char *image, int *acqstatus) { IRAFPointer imraw0, imraw1, imraw4, imraw7, imspt1; int size, i, status; char rawfile[SZ_FNAME], sptfile[SZ_FNAME], obsmode[FITS_LINE]; FILE *fp; /* for internal ta monitoring */ imageinfo *keywords; /* Build the appropriate string for raw & spt files spt file. */ strcpy (rawfile, image); size = strlen(rawfile) - 9; for (i=0; idomfgs, FITS_LINE-1); c_imgstr (imspt1, "sgestar", keywords->subfgs, FITS_LINE-1); c_imunmap (imspt1); } else { keywords->domfgs[0] = '\0'; keywords->subfgs[0] = '\0'; } PrintOutput (keywords, acqstatus); c_imunmap (imraw1); c_imunmap (imraw4); } /* Close primary header image. */ c_imunmap (imraw0); /* Deallocates memory for structures. */ free (keywords); return(0); } static void ReadKeywords (IRAFPointer imraw0, IRAFPointer imraw1, IRAFPointer imraw4, IRAFPointer imvar, imageinfo *keywords) { int centera1, centera2, ngoodpix, i, j, offset; double x, linenum, visit, goodmean; int *idwell; /* Read keywords from primary header. */ c_imgstr (imraw0, "rootname", keywords->rootname, FITS_LINE-1); c_imgstr (imraw0, "obsmode", keywords->obsmode, FITS_LINE-1); c_imgstr (imraw0, "aperture", keywords->aperture, FITS_LINE-1); c_imgstr (imraw0, "targname", keywords->targname, FITS_LINE-1); c_imgstr (imraw0, "tdateobs", keywords->tdateobs, FITS_LINE-1); c_imgstr (imraw0, "ttimeobs", keywords->ttimeobs, FITS_LINE-1); c_imgstr (imraw0, "opt_elem", keywords->optelem, FITS_LINE-1); keywords->proposid = c_imgeti (imraw0, "proposid"); keywords->sizaxis1 = c_imgeti (imraw0, "sizaxis1"); keywords->sizaxis2 = c_imgeti (imraw0, "sizaxis2"); keywords->texptime = c_imgetd (imraw0, "texptime"); keywords->biaslev = c_imgetd (imraw0, "biaslev"); centera1 = c_imgeti (imraw0, "centera1"); centera2 = c_imgeti (imraw0, "centera2"); ngoodpix = c_imgeti (imraw1, "ngoodpix"); linenum = c_imgetd (imraw0, "linenum"); goodmean = c_imgetd (imraw1, "goodmean"); /* Read keywords from the ACQ primary header. */ if ( strcmp(keywords->obsmode, "ACQ") == 0 ) { c_imgstr (imraw0, "acqtype", keywords->acqtype, FITS_LINE-1); if ( strcmp(keywords->acqtype, "POINT") == 0 ) strcpy (keywords->search, "FLUX CENTROID"); else c_imgstr (imraw0, "centmeth", keywords->search, FITS_LINE-1); keywords->box_step = c_imgeti (imraw0, "checkbox"); keywords->counts1= c_imgetd (imraw1, "maxchcnt"); keywords->counts2= c_imgetd (imraw4, "maxchcnt"); keywords->targax1 = c_imgetd (imraw1, "targa1"); keywords->targay1 = c_imgetd (imraw1, "targa2"); keywords->targax4 = c_imgetd (imraw4, "targa1"); keywords->targay4 = c_imgetd (imraw4, "targa2"); keywords->apera1 = c_imgetd (imvar, "apera1"); keywords->apera2 = c_imgetd (imvar, "apera2"); keywords->aperlka1 = c_imgetd (imvar, "aperlka1"); keywords->aperlka2 = c_imgetd (imvar, "aperlka2"); } /* Read keywords from the ACQ/PEAK primary header. */ if ( strcmp(keywords->obsmode, "ACQ/PEAK") == 0 ) { c_imgstr (imraw0, "peakcent", keywords->peakcent, FITS_LINE-1); c_imgstr (imraw0, "pksearch", keywords->search, FITS_LINE-1); keywords->box_step = c_imgeti (imraw0, "numsteps"); keywords->peakstep = c_imgetd (imraw0, "peakstep"); /* From spt[1] header */ keywords->otaslwa1 = c_imgeti (imvar, "otaslwa1"); keywords->otaslwa2 = c_imgeti (imvar, "otaslwa2"); } /* Calculate visit & expnum from 'linenum'. */ x = modf(linenum, &visit); keywords->expnum = (linenum - visit) * 1000; keywords->visit = visit; /* Calculate corner from 'centera' & sizaxis'. */ keywords->corner1 = centera1 - keywords->sizaxis1/2; keywords->corner2 = centera2 - keywords->sizaxis2/2; /* Calculate coarse, fine local axis & reference aperture locations. */ /* For ACQs only. */ if ( strcmp(keywords->obsmode, "ACQ") == 0 ) { keywords->coarse1 = keywords->targax1 - (keywords->corner1 - 1) + 1; keywords->coarse2 = keywords->targay1 - (keywords->corner2 - 1) + 1; keywords->fine1 = keywords->targax4 - (keywords->corner1 - 1) + 1; keywords->fine2 = keywords->targay4 - (keywords->corner2 - 1) + 1; keywords->refaper1 = keywords->apera1 - (keywords->corner1 + 31) + 1; keywords->refaper2 = keywords->apera2 - (keywords->corner2 + 34) + 1; if ( keywords->box_step > 3 ) { offset = (keywords->box_step + 1)/2; keywords->refaper1 = keywords->refaper1 - offset; keywords->refaper2 = keywords->refaper2 - offset; } } /* Calculate post-slew flux, get pedestal (from raw file) & dwell fluxes. */ /* For ACQ/PEAKs only. */ if ( strcmp(keywords->obsmode, "ACQ/PEAK") == 0 ) { keywords->counts1 = ngoodpix * goodmean; /* post-slew flux */ keywords->counts2 = c_imgetd (imraw0, "pedestal"); /* Read dwell fluxes from 4th extension of raw file. */ keywords->naxis1 = c_imglen (imraw4,1); keywords->naxis2 = c_imglen (imraw4,2); for (j=1; j<=keywords->naxis2; j++) { idwell = c_imgl2i (imraw4,j); for (i=0; inaxis1; i++) (keywords->dwell)[j-1][i] = idwell[i]; } } } static void CalculateSlews (imageinfo *keywords) { double offset; double finalx, finaly, x; /* Slew calculation for ACQs. */ if ( strcmp(keywords->obsmode, "ACQ") == 0 ) { /* Define all possible apertures for ACQs. */ if ( strcmp(keywords->aperture, "F25NDQ1") == 0 ) offset = -1.24840; else if ( strcmp(keywords->aperture, "F25NDQ2") == 0 ) offset = -1.24840; else if ( strcmp(keywords->aperture, "F25NDQ3") == 0 ) offset = -1.24840; else if ( strcmp(keywords->aperture, "F25NDQ4") == 0 ) offset = -1.24840; else if ( strcmp(keywords->aperture, "F28X50LP") == 0 ) offset = -1.26850; else if ( strcmp(keywords->aperture, "F28X50OIII") == 0 ) offset = -1.26850; else if ( strcmp(keywords->aperture, "F28X50OII") == 0 ) offset = -1.31570; else if ( strcmp(keywords->aperture, "F25ND3") == 0 ) offset = -1.24840; else if ( strcmp(keywords->aperture, "F25ND5") == 0 ) offset = -1.24840; else offset = 0.0; /* Slews in pixels. */ keywords->a1coarse_pix = keywords->targax1 - offset - keywords->aperlka1 + 1; keywords->a2coarse_pix = keywords->targay1 - keywords->aperlka2 + 1; keywords->a1fine_pix = keywords->targax4 - offset - keywords->apera1; keywords->a2fine_pix = keywords->targay4 - keywords->apera2; keywords->a1total_pix = keywords->a1coarse_pix + keywords->a1fine_pix; keywords->a2total_pix = keywords->a2coarse_pix + keywords->a2fine_pix; /* Slews in arcseconds. */ keywords->a1coarse_arc = arcseconds (keywords->a1coarse_pix); keywords->a2coarse_arc = arcseconds (keywords->a2coarse_pix); keywords->a1fine_arc = arcseconds (keywords->a1fine_pix); keywords->a2fine_arc = arcseconds (keywords->a2fine_pix); keywords->a1total_arc = arcseconds (keywords->a1total_pix); keywords->a2total_arc = arcseconds (keywords->a2total_pix); keywords->V2coarse = V2coord (keywords->a2coarse_arc,keywords->a1coarse_arc); keywords->V3coarse = V3coord (keywords->a1coarse_arc,keywords->a2coarse_arc); keywords->V2fine = V2coord (keywords->a2fine_arc,keywords->a1fine_arc); keywords->V3fine = V3coord (keywords->a1fine_arc,keywords->a2fine_arc); keywords->V2total = V2coord (keywords->a2total_arc,keywords->a1total_arc); keywords->V3total = V3coord (keywords->a1total_arc,keywords->a2total_arc); } /* Slew calculations for ACQ/PEAKs. */ else { if ( strcmp(keywords->search, "LINEARAXIS2") == 0 ) { finalx = (keywords->box_step/2)*keywords->peakstep/(PLATESCALE*1000.0); finaly = 0.0; } else if ( strcmp(keywords->search, "LINEARAXIS1") == 0 ) { finalx = 0.0; finaly = (keywords->box_step/2)*keywords->peakstep/(PLATESCALE*1000.0); } else if ( strcmp(keywords->search, "SPIRAL") == 0 ) { x = modf(sqrt(keywords->box_step)/2, &finaly); finaly = (-1)*finaly * keywords->peakstep/(PLATESCALE*1000.0); x = modf(sqrt(keywords->box_step)/2, &finalx); finalx = (-1)*finalx * keywords->peakstep/(PLATESCALE*1000.0); } /* Final slews in pixels. */ keywords->a1total_pix = keywords->otaslwa1/10.0 + finaly; keywords->a2total_pix = keywords->otaslwa2/10.0 + finalx; if ( strcmp(keywords->search, "SPIRAL") == 0 ) if ( keywords->a2total_pix > -0.05 && keywords->a2total_pix < 0.05 ) keywords->a2total_pix = 0.0; if ( keywords->a1total_pix > -0.05 && keywords->a1total_pix < 0.05 ) keywords->a1total_pix = 0.0; /* Rounding up the pixel values up to the decimal place. */ keywords->a1total_pix = NINT (keywords->a1total_pix); keywords->a2total_pix = NINT (keywords->a2total_pix); /* Slews in arcseconds. */ keywords->a1total_arc = arcseconds (keywords->a1total_pix); keywords->a2total_arc = arcseconds (keywords->a2total_pix); keywords->V2total = V2coord (keywords->a2total_arc,keywords->a1total_arc); keywords->V3total = V3coord (keywords->a1total_arc,keywords->a2total_arc); } } static void PrintOutput (imageinfo *keywords, int *acqstatus) { int i, j; /* Print Top header. */ for (i=1; i<80; i++) printf ("%s", "="); printf ("\n"); if ( strcmp(keywords->obsmode, "ACQ") == 0 ) printf ("%8s HST/STIS MIRVIS %7s ACQ/%s\n", keywords->rootname, keywords->aperture, keywords->acqtype); else printf ("%8s HST/STIS %s %7s ACQ/PEAK-UP\n", keywords->rootname, keywords->optelem, keywords->aperture); printf ("prop: %4d visit: %.0f line: %.0f target: %s\n", keywords->proposid, keywords->visit, keywords->expnum, keywords->targname); printf ("obs date, time: %8s %8s exposure time: %5.2f\n", keywords->tdateobs, keywords->ttimeobs, keywords->texptime); if ( strcmp(keywords->domfgs, "") != 0 || strcmp(keywords->subfgs, "") != 0 ) printf ("dom GS/FGS: %s sub-dom GS/FGS: %s\n", keywords->domfgs, keywords->subfgs); if ( strcmp(keywords->obsmode, "ACQ") == 0 ) printf ("ACQ params: bias sub: %.0f checkbox: %d method: %s\n", keywords->biaslev, keywords->box_step, keywords->search); else printf ("ACQ params: bias sub: %.0f method: %s\n", keywords->biaslev, keywords->peakcent); printf ("subarray (axis1,axis2): size=(%d,%d) corner=(%d,%d)\n", keywords->sizaxis1, keywords->sizaxis2, keywords->corner1, keywords->corner2 ); for (i=1; i<80; i++) printf ("%s", "-"); printf ("\n"); /* Print rest of output according to data type: ACQ or ACQ/PEAK. */ if ( strcmp(keywords->obsmode, "ACQ") == 0 ) { printf ("Coarse locate phase: Target flux in max checkbox (DN): %.0f\n\n", keywords->counts1); printf (" global local\n"); printf (" axis1 axis2 axis1 axis2\n"); printf ("Target location: %4.1f %4.1f %4.1f %4.1f\n\n", keywords->corner1 + keywords->coarse1 -1, keywords->corner2 + keywords->coarse2 -1, keywords->coarse1, keywords->coarse2); printf (" axis1 axis2 axis1 axis2 V2 V3\n"); printf (" (pixels) (arcsec) (arcsec)\n"); printf ("Estimated slew: %4.1f %4.1f %6.3f %6.3f %6.3f %6.3f\n", keywords->a1coarse_pix, keywords->a2coarse_pix, keywords->a1coarse_arc, keywords->a2coarse_arc, keywords->V2coarse, keywords->V3coarse); /* Print slews */ for (i=1; i<80; i++) printf ("%s", "-"); printf ("\n"); printf ("Fine locate phase: Target flux in max checkbox (DN): %.0f\n\n", keywords->counts2); printf (" global local\n"); printf (" axis1 axis2 axis1 axis2\n"); printf ("Target location: %4.1f %4.1f %4.1f %4.1f\n", keywords->corner1 + keywords->fine1 -1, keywords->corner2 + keywords->fine2 -1, keywords->fine1, keywords->fine2); printf ("Ref ap location: %4.1f %4.1f %4.1f %4.1f\n\n", keywords->apera1 + 1, keywords->apera2 + 1, keywords->refaper1, keywords->refaper2); printf (" axis1 axis2 axis1 axis2 V2 V3\n"); printf (" (pixels) (arcsec) (arcsec)\n"); printf ("Estimated slew: %4.1f %4.1f %6.3f %6.3f %6.3f %6.3f\n", keywords->a1fine_pix, keywords->a2fine_pix, keywords->a1fine_arc, keywords->a2fine_arc, keywords->V2fine, keywords->V3fine); /* Print slews */ for (i=1; i<80; i++) printf ("%s", "-"); printf ("\n"); printf ("Total est. slew: %4.1f %4.1f %6.3f %6.3f %6.3f %6.3f\n", keywords->a1total_pix, keywords->a2total_pix, keywords->a1total_arc, keywords->a2total_arc, keywords->V2total, keywords->V3total); for (i=1; i<80; i+=1) printf ("%s", "-"); printf ("\n"); PrintWarnings (keywords, acqstatus); } else { printf ("Scan type: %s Step size (mas): %.0f\n", keywords->search, keywords->peakstep); if ( strcmp(keywords->search, "SPIRAL") == 0 ) printf ("axis 1 -->, axis 2 ^\n"); printf ("\n"); /* Print here the dwell point values */ if ( strcmp(keywords->search, "LINEARAXIS2") == 0 ) { for (i=0; inaxis2; i++) for (j=keywords->naxis1; j>0; j--) printf ("%10d", (keywords->dwell)[i][j-1]); } else for (i=keywords->naxis2; i>0; i--) { for (j=0; jnaxis1; j++) printf ("%10d", (keywords->dwell)[i-1][j]); printf ("\n"); } printf ("\n\n"); printf (" axis1 axis2 axis1 axis2 V2 V3\n"); printf (" (pixels) (arcsec) (arcsec)\n"); printf ("Estimated slew: %4.1f %4.1f %6.3f %6.3f %6.3f %6.3f\n", keywords->a1total_pix, keywords->a2total_pix, keywords->a1total_arc, keywords->a2total_arc, keywords->V2total, keywords->V3total); printf ("Flux in post-slew confirmation image (%.0f) - Pedestal (%.0f) = %.0f DN\n", keywords->counts1, keywords->counts2, keywords->counts1 - keywords->counts2); for (i=1; i<80; i+=1) printf ("%s", "-"); printf ("\n"); PrintWarnings (keywords, acqstatus); } for (i=1; i<80; i+=1) printf ("%s", "="); printf ("\n"); } static void PrintWarnings (imageinfo *keywords, int *acqstatus) { double ratio, max; int i, j, badacq = 0; /* ACQ warnings. */ if ( strcmp(keywords->obsmode, "ACQ") == 0 ) { if ( (keywords->a1fine_pix < -4.0 || keywords->a1fine_pix > 4.0) || (keywords->a2fine_pix < -4.0 || keywords->a2fine_pix > 4.0) ) { printf ("The fine slew (to center the target in the reference aperture) is\n"); printf ("larger than 4 pixels. This may indicate a problem with your acquisition\n\n"); badacq = 1; } /* Ratio of flux in max checkbox in coarse & fine stages. */ ratio = keywords->counts1/keywords->counts2; if ( ratio < 0.9 || ratio > 1.1 ) { printf ("The ratio of the fluxes in the maximum checkbox in the coarse and fine\n"); printf ("stages differ by more than 10%%. This may indicate a problem with your\n"); printf ("acquisition\n\n"); badacq = 1; } if ( badacq == 0 ) { printf ("Your ACQ appears to have succeeded, as the flux ratio in the coarse\n"); printf ("and fine stages agree within 10%% and the fine slews were less than\n"); printf ("4 pixels as expected\n\n"); } } /* ACQ/PEAK warnings. */ if ( strcmp(keywords->obsmode, "ACQ/PEAK") == 0 ) { /* Calculate maximum flux in the peakup */ max = 0.0; for (j=1; j<=keywords->naxis2; j++) { for (i=0; inaxis1; i++) max = MAX(max,(keywords->dwell)[j-1][i]); } if ( (keywords->counts1 - keywords->counts2) < FLUX_CUTOFF * max ) { printf ("The flux in the confirmation image is less than %2.0f%% of the maximum flux\n", FLUX_CUTOFF * 100.); printf ("in the ACQ/PEAK scan. This implies that the ACQ/PEAK did not succeed.\n\n"); badacq = 1; } /* Search for the word FAILED in keyword PEAKCENT. */ /* This will check if flux test failed. */ if ( strstr(keywords->peakcent, "FAILED") != NULL ) { printf ("The ACQ/PEAK flux test failed, which means that no point in the peakup\n"); printf ("scan has a flux that is at least 30%% higher than any other point. The\n"); printf ("ACQ/PEAK has failed, and the telescope has returned to the initial\n"); printf ("position of the ACQ/PEAK\n\n"); badacq = 1; } /* If first & last flux values in LINEAR scans are 0. */ if ( strcmp(keywords->search, "LINEARAXIS1") == 0 ) { if ( (keywords->dwell)[0][0] != 0 && (keywords->dwell)[0][keywords->naxis1 - 1] != 0 ) { printf ("The minimum value in the scan did not occur at an end. This may indicate a\n"); printf ("problem with a neighboring object that could affect the acquisition.\n\n"); badacq = 1; } } else if ( strcmp(keywords->search, "LINEARAXIS2") == 0 ) { if ( (keywords->dwell)[0][0] != 0 && (keywords->dwell)[keywords->naxis2 - 1][0] != 0 ) { printf ("The minimum value in the scan did not occur at an end. This may indicate a\n"); printf ("problem with a neighboring object that could affect the acquisition.\n\n"); badacq = 1; } } if ( badacq == 0 ) { printf ("Your ACQ/PEAK appears to have succeeded, as the (scaled) flux in the\n"); printf ("confirmation image is greater than %2.0f%% of the maximum flux in any stage\n", FLUX_CUTOFF * 100.); printf ("of the peakup.\n\n"); } } /* Note that acqstatus is set if badacq is bad, but acqstatus is not reset if badacq is OK. */ if (badacq) *acqstatus = 1; } static void WriteError (int errcode, char *infile) { if (errcode == 827) printf ("Can't open %s; skipping ...\n", infile); else printf ("ERROR (IRAF) %d: %s\n", c_iraferr(), c_iraferrmsg()); } static double arcseconds (double x) { return (x * PLATESCALE); } static double V2coord (double x, double y) { return (COSTHETA*x + SINTHETA*y); } static double V3coord (double x, double y) { return (COSTHETA * x - SINTHETA * y); } static int tastis_immap (char *infile, char *extn, IRAFPointer *im) { char *filename; if ((filename = calloc (SZ_FNAME, sizeof(char))) == NULL ) { printf ("Out of memory.\n"); return (FATAL_ERROR); } strcpy (filename, infile); strcat (filename, extn); *im = c_immap (filename, IRAF_READ_ONLY, 0); if ( c_iraferr() ) { printf ("Error opening %s\n", filename); *im = 0; return (c_iraferr()); } free (filename); return (0); }