int GetSingle (AsnInfo *asn, ACSInfo *acs) { /* arguments: AsnInfo *asn i: calibration flags and other info ACSInfo *acs o: exposure specific flags and info */ extern int status; char rootname[CHAR_FNAME_LENGTH]; *rootname = '\0'; void FindAsnRoot (const char *, char *); const char * outroot = asn->filename; /* Make sure we are only passing a rootname, and not a full filename.*/ FindAsnRoot (outroot, rootname); strcpy (acs->outroot, rootname); strcpy (acs->rootname, rootname); if (asn->debug) { sprintf (MsgText, "GetSingle: Rootname: %s, Output rootname: %s",rootname, outroot); trlmessage (MsgText); } /* Check to see that this value of rootname is what we really need... */ strcpy (acs->asn_table, asn->asn_table); strcpy (acs->rawfile, asn->filename); /* Set sci_* flags for acs */ acs->sci_crcorr = asn->crcorr; acs->sci_dthcorr = asn->dthcorr; acs->sci_rptcorr = asn->rptcorr; acs->detector = asn->detector; acs->nimages = 1; /* Set MemType appropriate for output */ acs->mtype[0] = '\0'; return (status); }
int AcsSum (char *input, char *output, char *mtype, int printtime, int verbose) { extern int status; IRAFPointer tpin; AcsSumInfo acs; IODescPtr im; /* descriptor for input image */ Hdr phdr; /* primary header for input image */ int nimgs; int i; char acs_input[CHAR_FNAME_LENGTH]; int FileExists (char *); void TimeStamp (char *, char *); void PrBegin (char *); void PrEnd (char *); void PrFileName (char *, char *); void PrHdrInfo (char *, char *, char *, char *); int MkName (char *, char *, char *, char *, char *, int); void WhichError (int); void InitSumTrl (char *input, char *output); void FindAsnRoot (char *, char *); int mkNewSpt (char *, char *, char *); /* Determine input and output trailer files, then initialize output file by combining inputs into output file */ InitSumTrl (input, output); PrBegin ("ACSSUM"); nimgs = 0; if (printtime) TimeStamp ("ACSSUM started", ""); /* open the input file template */ tpin = c_imtopen (input); nimgs = c_imtlen(tpin); /* Initialize structure containing acssum information. */ AcsInit (&acs,nimgs); /* Copy command-line arguments into acs. */ for (i = 0; i < nimgs; i++) { c_imtgetim (tpin, acs.input[i], CHAR_FNAME_LENGTH); PrFileName ("input", acs.input[i]); } /* close file template */ c_imtclose (tpin); strcpy (acs.output, output); acs.printtime = printtime; acs.verbose = verbose; PrFileName ("output", acs.output); FindAsnRoot (output, acs.rootname); initHdr (&phdr); /* Check whether the output file already exists. */ if (FileExists (acs.output)) { FreeAcsInput (acs.input, nimgs); return (status); } strcpy(acs_input,acs.input[0]); /* Open input image in order to read its primary header. */ im = openInputImage (acs_input, "", 0); if (hstio_err()) { FreeAcsInput (acs.input, nimgs); return (status = OPEN_FAILED); } getHeader (im, &phdr); /* get primary header */ if (hstio_err()) { FreeAcsInput (acs.input, nimgs); return (status = OPEN_FAILED); } closeImage (im); /* Get keyword values from primary header. */ if (GetSumKeyInfo (&acs, &phdr)) { FreeAcsInput (acs.input, nimgs); return (status); } freeHdr (&phdr); /* Print information about this image. */ PrHdrInfo (acs.aperture, acs.filter1, acs.filter2, acs.det); if (acs.printtime) TimeStamp ("Begin processing", acs.rootname); /* Sum all imsets. */ if (SumGrps (&acs,mtype)){ FreeAcsInput (acs.input, nimgs); return (status); } /* create new SPT file for output product */ if (mkNewSpt (input, mtype, output)) { return(status); } /* Done... */ trlmessage ("\n"); PrEnd ("ACSSUM"); if (acs.printtime) TimeStamp ("ACSSUM completed", acs.rootname); /* Write out temp trailer file to final file */ WriteTrlFile (); FreeAcsInput (acs.input, nimgs); return (status); }
int SetInput (AsnInfo *asn) { /* Arguments: ** asn io: Association info structure */ extern int status; /* Local Variables */ char filename[SZ_FNAME+1]; int exist; /* EXISTS_YES or EXISTS_NO */ int in_dot; char linput[SZ_FNAME+1]; /* Lower case version of input */ int incase; /* What kind of input do we have? */ int DoesFileExist (char *); char *lowcase (char *, char *); int GetAsnName (char *, char *); void FindAsnRoot (char *, char *); /* Initialize internal variables here... */ filename[0] = '\0'; /* convert input to lowercase for use only in looking for extensions */ lowcase (linput, asn->input); /* Determine what kind of input: root only, ** root + suffix, or ** root + suffix + extension ** We will look for '.fit' or '.fits' extensions. */ /* First, let's complete the input filename with a FITS extension.*/ if (strstr(linput, ".fit") == NULL) { strcpy (filename, asn->input); strcat (filename, ".fits"); } else { strcpy (filename, asn->input); strcat (filename, "\0"); } /* Initialize local variable */ incase = 0; /* Now, we find out what kind of input name was provided... */ if (strstr(linput, "_asn") != NULL){ incase = 0; } else if (strstr(linput, "_raw") != NULL ) { incase = 1; } else if (!IsProduct (linput)) { /* Not a sub-product/intermediate product... */ incase = 2; } else { /* treat as if it was only a rootname (plus '.fits') */ incase = 3; } if (asn->debug) { sprintf (MsgText, "GetAsnTable: incase = %d",incase); trlmessage (MsgText); } /* Given this full filename for a file which exists, ** copy out just the rootname. */ FindAsnRoot(filename, asn->rootname); /* Can we find the file as it is input? */ exist = DoesFileExist(filename); /* Treat filename according to what was input... */ switch (incase) { case 0: /* We have an ASN file explicitly specified */ if (exist == EXISTS_YES) { /* Found an ASN file: Set values in ASN structure */ asn->process = FULL; strcpy(asn->asn_table, filename); strcpy(asn->filename, filename); if (asn->verbose) { trlmessage ("Processing FULL ASN table..."); } } else { /* Couldn't find specified ASN file... */ sprintf (MsgText, "File %s not found for processing", filename); trlerror (MsgText); return (status = OPEN_FAILED); } break; case 1: /* We have a RAW file explicitly specified */ if (exist == EXISTS_YES) { /* Found a RAW file: Set values in ASN structure */ strcpy (asn->filename, filename); strcpy (asn->asn_table, filename); strcat (asn->asn_table, "\0"); if (asn->verbose) { sprintf (MsgText, "Processing SINGLE image %s...", asn->filename); trlmessage (MsgText); } asn->process = SINGLE; } else { /* Couldn't find specified RAW file... */ sprintf (MsgText,"File %s not found for processing", filename); trlerror (MsgText); return (status = OPEN_FAILED); } break; case 2: /* We have a sub-product/intermediate file specified ** for re-processing. They should really just run the ** stand-alone tasks separately by hand, but... */ if (exist == EXISTS_YES) { strcpy (asn->filename, filename); /* Look for ASN_TAB in file's header, and copy to ** ASN->asn_table if it is found. */ if (!GetAsnName (filename, asn->asn_table) ) { /* No ASN table listed, process as a ** SINGLE exposure */ asn->process = SINGLE; if (asn->verbose) { trlmessage ("Re-Processing a SINGLE image from ASN table..."); } } else { /* ASN table given in file, PARTIALLY process ** table */ asn->process = PARTIAL; if (asn->verbose) { trlmessage ("Re-Processing PART of ASN table..."); } } } else { /* Couldn't find specified file... */ sprintf (MsgText,"File %s not found for re-processing", filename); trlerror (MsgText); return (status = OPEN_FAILED); } break; case 3: /* We only have a rootname (with .fits extension) ** specified */ default: if (exist == EXISTS_YES) { strcpy (asn->filename, filename); /* Look for ASN_TAB in file's header, and copy to ** ASN->asn_table if it is found. */ if (!GetAsnName (filename, asn->asn_table)) { /* No ASN table listed, process as a SINGLE ** exposure */ asn->process = SINGLE; if (asn->verbose) { trlmessage ("Processing a SINGLE image from ASN table..."); } } else { /* ASN table given in file, PARTIALLY process ** table */ asn->process = PARTIAL; if (asn->verbose) { trlmessage ("Processing PART of ASN table..."); } } } else { /* Let's start fresh, shall we? At this point we only ** have as rootname and (maybe) a .fits extension... in_dot = strcspn (filename, ".fit"); */ in_dot = strlen(filename) - strlen(strstr (filename, ".fit")); if (asn->debug){ sprintf (MsgText, "For file %s, in_dot = %d", filename, in_dot); trlmessage (MsgText); } /* Truncate extension off of filename */ filename[in_dot] = '\0'; /* Create full ASN table name from input rootname */ strcat (filename, "_asn.fits"); exist = DoesFileExist (filename); if (exist == EXISTS_YES) { strcat (filename, "\0"); /* If a name was specified, the file must exist. */ strcpy (asn->asn_table, filename); if (asn->verbose) { trlmessage ("Found and processing FULL ASN table..."); } asn->process = FULL; } else { /* Couldn't find ASN file, so ** trim off suffix previously tested. */ in_dot = strlen (filename) - strlen (strstr(filename, "_asn")) ; filename[in_dot] = '\0'; /* ... and look for RAW file */ strcat (filename, "_raw.fits"); exist = DoesFileExist (filename); if (exist == EXISTS_YES) { /* Found a RAW file; ** Set values in ASN structure */ strcat (filename, "\0"); strcpy (asn->asn_table, filename); if (asn->verbose) { trlmessage ("Processing a SINGLE image from ASN table..."); } asn->process = SINGLE; } else { /* Is INPUT the rootname of a product which ** hasn't been created yet? */ /* Extract just the rootname plus last character ** of rootname (which may be the subproduct ID*/ in_dot = strlen (filename) - strlen (strstr (filename, "_raw")); filename[in_dot -1] = '\0'; /* Replace last character of filename with ** 0_asn.fits */ strcat (filename, "0_asn.fits"); exist = DoesFileExist (filename); if (exist == EXISTS_YES) { strcpy (asn->asn_table, filename); if (asn->verbose) { trlmessage ("PARTIAL processing of ASN table..."); } asn->process = PARTIAL; } else { /* We can't find a matching file or ASN ** table to process */ sprintf (MsgText, "File %s not found for processing", filename); trlerror (MsgText); return (status = OPEN_FAILED); } } } } /* End of Exists ELSE statement for this case */ break; /* End of Case 3 and DEFAULT case */ } /* End of switch statement */ if (asn->debug) { trlmessage ("SetInput: Determined what ASN table to process and how."); } return (status); }
/* GETASNMEMBER: Copy information from association table structure ** to a single image structure for use by the remainder of the ** processing tasks. */ int GetAsnMember (AsnInfo *asn, int prodid, int posid, int expid, ACSInfo *acs) { /* arguments: AsnInfo *asn i: calibration flags and other info int prodid i: product id for exposure int posid i: sub-product id for exposure int expid i: id of exposure within sub-product ACSInfo *acs o: exposure specific flags and info */ extern int status; char rootname[CHAR_FNAME_LENGTH+1]; char mtype[SZ_STRKWVAL+1]; int mlen; void FindAsnRoot (const char *, char *); void UpperAll (char *, char *, int); /* find out if the member we want exists... */ if (asn->product[prodid].subprod[posid].exp[expid].name[0] == '\0') { sprintf(MsgText,"Couldn't find exposure %d of sub-product %d for product %d. ", expid, posid, prodid); trlerror (MsgText); return (status = NO_GOOD_DATA); } /* Initialize local strings... */ rootname[0] = '\0'; mtype[0] = '\0'; const char * outroot = asn->product[prodid].subprod[posid].name; /* Make sure we are only passing a rootname, and not a full filename.*/ FindAsnRoot (outroot, rootname); strcpy (acs->outroot, rootname); strcpy (acs->rootname, asn->product[prodid].subprod[posid].exp[expid].name); strcpy (acs->crj_root, asn->product[prodid].subprod[posid].spname); /* Make sure we are only passing a rootname, and not a full filename.*/ FindAsnRoot (acs->rootname, rootname); strcpy (acs->rootname, rootname); if (asn->debug){ sprintf (MsgText, "GetAsnMember: Rootname: %s, Output rootname: %s",rootname, outroot); trlmessage (MsgText); } /* Check to see that this value of rootname is what we really need... */ strcpy (acs->asn_table, asn->asn_table); strcpy (acs->rawfile, asn->product[prodid].subprod[posid].exp[expid].expname); /* Set sci_* flags for acs */ acs->sci_crcorr = asn->crcorr; acs->sci_dthcorr = asn->dthcorr; acs->sci_rptcorr = asn->rptcorr; acs->detector = asn->detector; acs->nimages = asn->spmems[posid]; /* Set MemType appropriate for output */ if (!strncmp (rootname, acs->asn_table, 8) ) { mlen = strlen(acs->mtype); UpperAll (acs->mtype, mtype, mlen); strcpy(mtype, asn->product[prodid].subprod[posid].mtype); } return (status); }
/* acsrej_do -- Perform the cosmic ray rejection for ACS images Description: ------------ This is mostly a file bookkeeping routine for the cosmic ray rejection task. It takes care of input/output files open/close, check for dimensions, read/ write data from/to files, allocate memory spaces etc. Date Author Description ---- ------ ----------- 06-May-1996 J.-C. Hsu Adapt from the SPP code crrej_do.x 05-Aug-1998 W. Hack Modified to handle ACS data 11-Feb-1999 W. Hack EXPTIME now in Pri. Hdr. 18-Mar-1999 W.J. Hack Revised to read EXPTIMEs from Primary headers for cr_scaling using tpin directly 14-Sep-1999 W.J. Hack Cleaned up SHADCORR usage. Added check for max number of files here. */ int acsrej_do (IRAFPointer tpin, char *outfile, char *mtype, clpar *par, int newpar[]) { extern int status; IODescPtr ipsci[MAX_FILES]; /* science image descriptor */ IODescPtr ipdq[MAX_FILES]; /* data quality image descriptor */ float skyval[MAX_FILES]; /* background DN values */ float efac[MAX_FILES]; /* exposure factors */ multiamp noise; /* readout noise */ multiamp gain; /* A-to-D gain factors */ float exptot; float texpt; int nimgs; SingleGroup sg; int niter = 0; float sigma[MAX_ITER]; Hdr phdr; /* primary header */ int extver; /* Current extension being processed*/ int numext; /* Number of extensions in each image */ int nextend; /* Number of output extensions */ char imgname[MAX_FILES][CHAR_FNAME_LENGTH]; char fimage[CHAR_FNAME_LENGTH]; /* Name of first image in list */ char root[CHAR_FNAME_LENGTH]; /* ROOTNAME for output CRJ file */ char uroot[CHAR_FNAME_LENGTH]; /* Upper case version of rootname */ char *shadrefname; int ext[MAX_FILES]; int dim_x, dim_y; /* image dimensions */ int i, j, n; /* loop indices */ float *efacsum, *work; int nrej; /* total number of rejected pixels */ float skysum; /* total sky level */ int logit; RefImage shadref; int shadswitch; double expend, expstart; int non_zero; /* number of input images with EXPTIME>0.*/ int found; char imgdefault[CHAR_FNAME_LENGTH]; /* name of first input image with EXPTIME > 0. */ int GetSwitch (Hdr *, char *, int *); int UpdateSwitch (char *, int, Hdr *, int *); void InitRefImg (RefImage *); int ImgHistory (const RefImage *, Hdr *); int ImgPedigree (RefImage *); int acsrej_check (IRAFPointer, int, int, clpar *, int [], char [][CHAR_FNAME_LENGTH], int [], IODescPtr [], IODescPtr [], multiamp *, multiamp *, int *, int *, int); int cr_scaling (char *, IRAFPointer, float [], int *, double *, double *); int rejpar_in(clpar *, int [], int, float, int *, float []); void acsrej_sky (char *, IODescPtr [], IODescPtr [], int, short, float []); void cr_history (SingleGroup *, clpar *, int); int acsrej_init (IODescPtr [], IODescPtr [], clpar *, int, int, int, multiamp, multiamp, float [], float [], SingleGroup *, float *); int acsrej_loop (IODescPtr [], IODescPtr [], char [][CHAR_FNAME_LENGTH], int [], int, clpar *, int, int, int, float [], multiamp, multiamp, float [], float [], FloatTwoDArray *, FloatTwoDArray *, float *, ShortTwoDArray *, int *, char *); int PutKeyFlt (Hdr *, char *, float, char *); int PutKeyDbl (Hdr *, char *, double, char *); int PutKeyStr (Hdr *, char *, char *, char *); int GetKeyStr (Hdr *, char *, int, char *, char *, int); int PutKeyInt (Hdr *, char *, int, char *); int GetKeyInt (Hdr *, char *, int, int, int *); void UFilename (char *, Hdr *); void UMemType (char *, Hdr *); void UExpname (char *, Hdr *); int LoadHdr (char *, Hdr *); void UpperAll (char *, char *, int); void TimeStamp (char *, char *); void WhichError (int); void PrSwitch (char *, int); void FindAsnRoot (char *, char *); void initmulti (multiamp *); /* -------------------------------- begin ---------------------------------- */ /* Initialize necessary structures */ InitRefImg (&shadref); root[0] = '\0'; uroot[0] = '\0'; initmulti (&noise); initmulti (&gain); numext = 0; nextend = 0; /* Since CR-SPLIT images are in separate files, we need to combine the same chip's exposure from each file. Therefore we will loop over each extension in the first image, determine what chip that corresponds to, and get the same chip from the rest of the images (which could be in any arbitrary extension in each of the images). */ /* First, let's determine how many extensions/chips in each file */ c_imtgetim (tpin, fimage, CHAR_FNAME_LENGTH); if (LoadHdr (fimage, &phdr) ) return (status = ERROR_RETURN); if (GetKeyInt (&phdr, "NEXTEND", NO_DEFAULT, 0, &nextend) == 0) numext = nextend / EXT_PER_GROUP; else numext = 1; shadswitch = 0; /* Check to see if SHADCORR was set to PERFORM in image header */ if (GetSwitch (&phdr, "SHADCORR", &shadswitch) ) return(status); /* If shadcorr was set either by the user on the command line or in the image header, initialize shadcorr processing. */ if (par->shadcorr == PERFORM || shadswitch == PERFORM) { /* Use par->shadcorr as switch for performing shading correction */ par->shadcorr = PERFORM; shadrefname = calloc(CHAR_FNAME_LENGTH, sizeof(char)); if (GetKeyStr (&phdr, "SHADFILE", NO_DEFAULT, "", shadrefname, CHAR_FNAME_LENGTH) ) return(status); strcpy (shadref.name, shadrefname); /* Read in PEDIGREE and DESCRIPTION for SHADFILE */ if (ImgPedigree (&shadref) ) return (status); /* If a DUMMY shadfile was specified, turn off shadcorr */ if (shadref.goodPedigree == DUMMY) par->shadcorr = OMIT; free (shadrefname); } freeHdr (&phdr); /* Initialize efac */ for (n = 0; n < MAX_FILES; n++) efac[n] = 1.0; /* calculate the scaling factors due to different exposure time */ strcpy (par->expname, "EXPTIME"); if (cr_scaling (par->expname, tpin, efac, &nimgs, &expend, &expstart) ){ WhichError (status); return (status); } /* make sure there is more than one image to process */ if (nimgs < 2) { trlmessage ("Needs more than one input image."); return (status = NOTHING_TO_DO); } /* calculate the total exposure time */ exptot = 0.; non_zero = 0; for (n = 0; n < nimgs; ++n) { exptot += efac[n]; /* Count how many inputs have non-zero(valid) EXPTIME */ if (efac[n] > 0.) non_zero++; } /* for the case of all images have zero exposure time, use equal exposure time of 1. */ if (exptot == 0.) { for (n = 0; n < nimgs; ++n) { efac[n] = 1.; } texpt = (float) nimgs; non_zero = nimgs; } else { texpt = exptot; } /* Now, start the loop. */ for (extver = 1; extver <= numext; extver++) { if (par->printtime) { TimeStamp ("Start cosmic ray rejection",""); } /* open input files and temporary files, check the parameters */ if (acsrej_check (tpin, extver, numext, par, newpar, imgname, ext, ipsci, ipdq, &noise, &gain, &dim_x, &dim_y, nimgs)) { WhichError (status); return(status); } /* Now that we have read in SHADCORR, report if it will be performed */ PrSwitch ("shadcorr", par->shadcorr); /* read in the parameters */ if (rejpar_in (par, newpar, nimgs, exptot, &niter, sigma) ) return(status); /* allocate array space */ efacsum = calloc (dim_x*dim_y, sizeof(float)); work = calloc (nimgs*dim_x, sizeof(float)); /* calculate the sky levels */ acsrej_sky (par->sky, ipsci, ipdq, nimgs, par->badinpdq, skyval); if (status != ACS_OK) { WhichError (status); return (status); } if (par->verbose) { for (n = 0; n < nimgs; n++) { sprintf (MsgText, "sky of '%s[sci,%d]' is %0.3f DN", imgname[n], ext[n], skyval[n]); trlmessage (MsgText); } } /* use the first input image to set up the data structure */ initSingleGroup (&sg); /* Find the first image in the input list which has an EXPTIME > 0. to use for initializing the output SingleGroup. */ found = 0; n = 0; /* By default, simply use the first one, so initialize accordingly.*/ strcpy (imgdefault, imgname[0]); do { if (efac[n] > 0.) { strcpy(imgdefault,imgname[n]); found = 1; } n++; } while (found == 0); getSingleGroup (imgdefault, extver, &sg); if (non_zero > 1){ /* compute the initial pixel values to be used to compare against all images. */ if (non_zero < nimgs){ trlwarn ("Some input exposures had EXPTIME = 0."); } if (acsrej_init (ipsci, ipdq, par, nimgs, dim_x, dim_y, noise, gain, efac, skyval, &sg, work) ) { WhichError(status); closeSciDq(nimgs, ipsci, ipdq, par); return (status); } if (par->printtime) TimeStamp ("Calculated initial guess for extension", ""); /* do the iterative cosmic ray rejection calculations */ if (acsrej_loop (ipsci, ipdq, imgname, ext, nimgs, par, niter, dim_x, dim_y, sigma, noise, gain, efac, skyval, &sg.sci.data, &sg.err.data, efacsum, &sg.dq.data, &nrej, shadref.name) ) { WhichError(status); closeSciDq(nimgs, ipsci, ipdq, par); return (status); } } else { trlwarn ("Cosmic-ray rejection NOT performed!"); if (non_zero > 0) { trlwarn ("Some input exposures had EXPTIME = 0."); trlwarn ("Output product will not be cosmic-ray cleaned!"); } /*else { trlwarn ("ALL input exposures had EXPTIME = 0."); trlwarn ("Output product will be BLANK!"); } */ } /* End if(non_zero) block */ /* must close all images, now that we are done reading them */ closeSciDq(nimgs, ipsci, ipdq, par); /* calculate the total sky ... */ skysum = 0.; for (n = 0; n < nimgs; ++n) { skysum += skyval[n]; } /* ... and force it to be non-negative */ if (skysum < 0.) skysum = 0.; if (par->printtime){ if (non_zero > 1){ TimeStamp ("Finished detecting cosmic rays on extension", ""); } else { TimeStamp ("Done checking this extension",""); } } /* write to the output image */ if (non_zero > 0){ for (j = 0; j < dim_y; ++j) { for (i = 0; i < dim_x; ++i) { PPix(&sg.sci.data,i,j) = PPix(&sg.sci.data,i,j)*texpt + skysum; PPix(&sg.err.data,i,j) *= texpt; } } } else { for (j = 0; j < dim_y; ++j) { for (i = 0; i < dim_x; ++i) { PPix(&sg.sci.data,i,j) = par->fillval; PPix(&sg.err.data,i,j) = 0.; /* Set DQ value to one which will always be considered BAD */ PPix(&sg.dq.data,i,j) = 1; } } /* Set at least one pixel to a different value to insure that an image array actually gets produced. */ PPix(&sg.err.data,0,0) = -1.; PPix(&sg.dq.data,0,0) = 8; } /* update the exposure time of the output images */ PutKeyFlt (sg.globalhdr, "TEXPTIME", exptot, ""); PutKeyFlt (sg.globalhdr, "SKYSUM", skysum, "Total sky level (DN)"); PutKeyDbl (sg.globalhdr, "EXPSTART", expstart, "computed exposure start time (Modified Julian Date)"); PutKeyDbl (sg.globalhdr, "EXPEND", expend, "exposure end time (Modified Julian Date)"); /* Updated REJ_RATE to use 'texpt' as a safe value when EXPTIME=0 for all members. WJH, 24 Feb 2003 */ PutKeyFlt (sg.globalhdr, "REJ_RATE", (float)nrej/texpt, "Cosmic ray impact rate (pixels/sec)"); PutKeyFlt (sg.globalhdr, "EXPTIME", exptot, ""); if (par->shadcorr) { logit = 0; if (UpdateSwitch ("SHADCORR", par->shadcorr, sg.globalhdr, &logit) ) return (status); PrSwitch ("shadcorr", COMPLETE); if (logit) { /*Records SHADFILE information in header comments... */ if (ImgHistory (&shadref, sg.globalhdr)) return (status); } } /* record parameters to the output file */ cr_history (&sg, par, nextend); PutKeyInt (&sg.sci.hdr, "NCOMBINE", nimgs, ""); UFilename (outfile, sg.globalhdr); UMemType (mtype, sg.globalhdr); FindAsnRoot (outfile, root); UpperAll (root, uroot, strlen(root)+1 ); /* EXPNAME values modified for all extensions in a SingleGroup. WJH 7 July 1999 */ UExpname (root, &sg.sci.hdr); UExpname (root, &sg.err.hdr); UExpname (root, &sg.dq.hdr); PutKeyStr (sg.globalhdr, "ROOTNAME", uroot,"Rootname of the observation set"); /* Output CHIP to the same EXTVER as the CHIP ID */ putSingleGroup (outfile, extver, &sg, 0); freeSingleGroup (&sg); if (par->printtime) TimeStamp ("Finished writing out extension", ""); /* deallocate memories */ free (efacsum); free (work); } /* Set status to a value which will be understood by CALACS to turn off subsequent processing. */ if (non_zero == 0) status = NO_GOOD_DATA; return (status); }