int doNoisIR (WF3Info *wf3, MultiNicmosGroup *input) { /* Arguments: ** wf3 i: WFC3 info structure ** input io: input image */ /* Function definitions */ int noiscalc (WF3Info *, SingleNicmosGroup *); int OmitStep (int); void PrSwitch (char *, int); /* Do the noise calculation for each group */ if (wf3->noiscorr == PERFORM) { for (wf3->group=wf3->ngroups; wf3->group >= 1; wf3->group--) { if (noiscalc (wf3, &(input->group[wf3->group-1]))) { PrSwitch ("noiscorr", SKIPPED); return (status=0); } } } /* Print status to trailer */ if (!OmitStep (wf3->noiscorr)) trlmessage ("Uncertainty array initialized."); PrSwitch ("noiscorr", COMPLETE); /* Successful return */ return (status = 0); }
int doBlevIR (WF3Info *wf3, MultiNicmosGroup *input, SingleNicmosGroup *zoff) { /* Arguments: ** wf3 i: WFC3 info structure ** input io: image to be bias corrected */ /* Local variables */ /* Function definitions */ int blevcorr (WF3Info *, SingleNicmosGroup *); void PrSwitch (char *, int); /* Do the bias correction for each group */ if (wf3->blevcorr == PERFORM) { for (wf3->group=wf3->ngroups; wf3->group >= 1; wf3->group--) { if (blevcorr (wf3, &(input->group[wf3->group-1]))) return (status); } if (blevcorr (wf3, zoff)) return (status); PrSwitch ("blevcorr", COMPLETE); } /* Successful return */ return (status = 0); }
int doNlinIR (WF3Info *wf3, MultiNicmosGroup *input, SingleNicmosGroup *zsig) { /* Arguments: ** wf3 i: WFC3 info structure ** input io: input image to be corrected ** zsig i: MULTIACCUM zero-read signal image */ /* Local variables */ NlinData nlin; /* Function definitions */ int getNlinData (WF3Info *, NlinData *); void freeNlinData (NlinData *); void satcheck (SingleNicmosGroup *, SingleNicmosGroup *); void PrSwitch (char *, int); /* Do the non-linearity correction for each group */ if (wf3->nlincorr == PERFORM) { /* Load the nlin reference file data */ if (getNlinData (wf3, &nlin)) return (status); /* Loop over MultiAccum groups */ for (wf3->group=wf3->ngroups; wf3->group >= 1; wf3->group--) { if (nlincorr (wf3, &(input->group[wf3->group-1]), &nlin, zsig)) return (status); /* Flag pixels in the next group as saturated if they're ** flagged as saturated in the current group */ if (wf3->group-1 > 0) satcheck (&(input->group[wf3->group-1]), &(input->group[wf3->group-2])); } freeNlinData (&nlin); PrSwitch ("nlincorr", COMPLETE); } /* Successful return */ return (status = 0); }
/* 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); }
int photcalc (WF3Info *wf3, MultiNicmosGroup *input) { /* Arguments: ** wf3 i: WFC3 info structure ** input io: input image */ /* Local variables */ PhotPar obs; float photfnu; char photmode[CHAR_LINE_LENGTH+1], obsmode[CHAR_LINE_LENGTH+1]; int status; /* Function definitions */ int GetKeyStr (Hdr *, char *, int, char *, char *, int); int PutKeyFlt (Hdr *, char *, float, char *); void PrSwitch (char *, int); if (wf3->photcorr == PERFORM) { /* Extract photmode from sci extension header */ if ( (status=GetKeyStr (input->group[0].globalhdr, "PHOTMODE", USE_DEFAULT, "", photmode, CHAR_LINE_LENGTH))) return (status); /* Convert PHOTMODE string into synphot OBSMODE syntax */ Phot2Obs (photmode, obsmode); if (wf3->verbose) { sprintf (MsgText, "Created obsmode of: %s", obsmode); trlmessage (MsgText); } /* Initialize PhotPar structure */ InitPhotPar (&obs, wf3->phot.name, wf3->phot.pedigree); /* Get the photometry values from the IMPHTTAB table */ if (GetPhotTab (&obs, obsmode)) { trlerror ("Error return GetPhotTab."); } if (wf3->verbose) { sprintf (MsgText, "Computed PHOTFLAM value of %g", obs.photflam); } /* Update the photometry keyword values in the header */ if (PutKeyFlt (input->group[0].globalhdr, "PHOTFLAM", obs.photflam, "")) return (status); if (PutKeyFlt (input->group[0].globalhdr, "PHOTZPT", obs.photzpt, "")) return (status); if (PutKeyFlt (input->group[0].globalhdr, "PHOTPLAM", obs.photplam, "")) return (status); if (PutKeyFlt (input->group[0].globalhdr, "PHOTBW", obs.photbw, "")) return (status); photfnu = 3.33564e+4 * obs.photflam * obs.photplam*obs.photplam; if (PutKeyFlt (input->group[0].globalhdr, "PHOTFNU", photfnu, "")) return (status); FreePhotPar (&obs); PrSwitch ("photcorr", COMPLETE); } /* Successful return */ return (status = 0); }
int WF3cte (char *input, char *output, CCD_Switch *cte_sw, RefFileInfo *refnames, int printtime, int verbose, int onecpu) { /* input: filename output: filename cte_sw: the calibration flags refnames: the names of the calibration reference files onecpu: use parallel processing? The following are new primary header keywords which will be added to the data so that they can be updated by the code. They are also specified in the PCTETAB reference file. These are taken from the PCTETAB CTE_NAME - name of cte algorithm CTE_VER - version number of cte algorithm CTEDATE0 - date of wfc3/uvis installation in HST, in MJD CTEDATE1 - reference date of CTE model pinning, in MJD PCTETLEN - max length of CTE trail PCTERNOI - readnoise amplitude for clipping PCTESMIT - number of iterations used in CTE forward modeling PCTESHFT - number of iterations used in the parallel transfer PCTENSMD - readnoise mitigation algorithm PCTETRSH - over-subtraction threshold PCTEFRAC - cte scaling frac calculated from expstart PCTERNOI - the readnoise clipping level to use #These are taken from getreffiles.c DRKCFILE is a new dark reference file used only in the CTE branch *_DRC.fits BIACFILE is a new super-bias reference file used only in the CTE branch *_BIC.fits PCTETAB is a new reference file FITS table which will contain the software parameter switches for the CTE correction *_CTE.fit This is the main workhorse function for removing the CTE from WFC3 UVIS images Unfortunately this happens before anything else in wfc3, so there's a lot of reading files at the beginning in order to populate needed information. The rest of the pipeline works on one chip at a time and the structures are all defined to support that. None of these structures are defined until the code enters the single chip loops. This differs from the CTE correction in ACS which occurs later in the process after basic structures are defined. */ extern int status; WF3Info wf3; /*structure with calibration switches and reference files for passing*/ Hdr phdr; /*primary header for input image, all output information saved here*/ CTEParams cte_pars; /*STRUCTURE HOLDING THE MODEL PARAMETERS*/ SingleGroup cd; /*SCI 1*/ SingleGroup ab; /*SCI 2*/ SingleGroup raz; /* THE LARGE FORMAT COMBINATION OF CDAB*/ SingleGroup rsz; /* LARGE FORMAT READNOISE CORRECTED IMAGE */ SingleGroup rsc; /* CTE CORRECTED*/ SingleGroup rzc; /* FINAL CTE CORRECTED IMAGE */ SingleGroup chg; /* THE CHANGE DUE TO CTE */ SingleGroup raw; /* THE RAW IMAGE IN RAZ FORMAT */ int i,j; /*loop vars*/ int max_threads=1; clock_t begin; double time_spent; float hardset=0.0; begin = (double)clock(); Bool subarray; /* to verify that no subarray is being used, it's not implemented yet*/ /*CONTAIN PARALLEL PROCESSING TO A SINGLE THREAD AS USER OPTION*/ # ifdef _OPENMP trlmessage("Using parallel processing provided by OpenMP inside CTE routine"); if (onecpu){ omp_set_dynamic(0); max_threads=1; sprintf(MsgText,"onecpu == TRUE, Using only %i threads/cpu", max_threads); } else { omp_set_dynamic(0); max_threads = omp_get_num_procs(); /*be nice, use 1 less than avail?*/ sprintf(MsgText,"Setting max threads to %i of %i cpus",max_threads, omp_get_num_procs()); } omp_set_num_threads(max_threads); trlmessage(MsgText); # endif /* COPY COMMAND-LINE ARGUMENTS INTO WF3. */ WF3Init (&wf3); strcpy (wf3.input, input); strcpy (wf3.output, output); PrBegin ("WFC3CTE"); if (wf3.printtime) TimeStamp("WFC3CTE Started: ",wf3.rootname); /* CHECK WHETHER THE OUTPUT FILE ALREADY EXISTS. */ if (FileExists (wf3.output)){ WhichError(status); return (ERROR_RETURN); } wf3.pctecorr = cte_sw->pctecorr; wf3.darkcorr = cte_sw->darkcorr; wf3.biascorr = cte_sw->biascorr; wf3.blevcorr = cte_sw->blevcorr; wf3.printtime = printtime; wf3.verbose = verbose; wf3.refnames = refnames; PrFileName ("input", wf3.input); PrFileName ("output", wf3.output); if (wf3.biascorr == COMPLETE){ trlmessage("BIASCORR complete for input image, CTE can't be performed"); return(ERROR_RETURN); } if (wf3.darkcorr == COMPLETE){ trlmessage("DARKCORR complete for input image, CTE can't be performed"); return(ERROR_RETURN); } if (wf3.blevcorr == COMPLETE){ trlmessage("BLEVCORR complete for input image, CTE can't be performed"); return(ERROR_RETURN); } /* DETERMINE THE NAMES OF THE TRAILER FILES BASED ON THE INPUT AND OUTPUT FILE NAMES, THEN INITIALIZE THE TRAILER FILE BUFFER WITH THOSE NAMES. */ if (initCTETrl (input, output)) return (status); /* OPEN INPUT IMAGE IN ORDER TO READ ITS PRIMARY HEADER. */ if (LoadHdr (wf3.input, &phdr) ){ WhichError(status); return (ERROR_RETURN); } /* GET KEYWORD VALUES FROM PRIMARY HEADER. */ if (GetKeys (&wf3, &phdr)) { freeHdr (&phdr); return (status); } if (GetCTEFlags (&wf3, &phdr)) { freeHdr(&phdr); return (status); } /* OPEN THE INPUT IMAGES AND GET THE SCIENCE EXTENSIONS */ initSingleGroup (&cd); getSingleGroup (wf3.input, 1, &cd); if (hstio_err()) return (status = OPEN_FAILED); /*** MAKE SURE THIS IS NOT A SUBARRAY ***/ if (GetKeyBool (cd.globalhdr, "SUBARRAY", NO_DEFAULT, 0, &subarray)) return (status=KEYWORD_MISSING); if (subarray) { sprintf(MsgText,"**SUBARRAY FOUND!; SUBARRAY images are not yet supported for CTE**"); trlmessage(MsgText); status=ERROR_RETURN; return(status); } initSingleGroup (&ab); getSingleGroup (wf3.input, 2, &ab); if (hstio_err()) return (status = OPEN_FAILED); if (GetKeyBool (ab.globalhdr, "SUBARRAY", NO_DEFAULT, 0, &subarray)) return (status=KEYWORD_MISSING); if (subarray) { sprintf(MsgText,"SUBARRAY FOUND; **SUBARRAY images are not yet supported for CTE**"); trlmessage(MsgText); status=ERROR_RETURN; return(status); } /*READ IN THE CTE PARAMETER TABLE*/ initCTEParams(&cte_pars); if (GetCTEPars (wf3.pctetab.name,&cte_pars)) return (status); if (verbose){ PrRefInfo ("pctetab", wf3.pctetab.name, wf3.pctetab.pedigree, wf3.pctetab.descrip, wf3.pctetab.descrip2); } /*SAVE THE PCTETABLE INFORMATION TO THE HEADER OF THE SCIENCE IMAGE AFTER CHECKING TO SEE IF THE USER HAS SPECIFIED ANY CHANGES TO THE CTE CODE VARIABLES. */ if (CompareCTEParams(&cd, &cte_pars)){ return (status); } /*SET UP THE ARRAYS WHICH WILL BE PASSED AROUND*/ initSingleGroup(&raz); allocSingleGroup(&raz, RAZ_COLS, RAZ_ROWS); initSingleGroup(&rsz); allocSingleGroup(&rsz, RAZ_COLS, RAZ_ROWS); initSingleGroup(&rsc); allocSingleGroup(&rsc, RAZ_COLS, RAZ_ROWS); initSingleGroup(&rzc); allocSingleGroup(&rzc, RAZ_COLS, RAZ_ROWS); initSingleGroup(&raw); allocSingleGroup(&raw, RAZ_COLS, RAZ_ROWS); initSingleGroup(&chg); allocSingleGroup(&chg, RAZ_COLS, RAZ_ROWS); for (i=0;i<RAZ_COLS;i++){ for(j=0;j<RAZ_ROWS;j++){ Pix(raw.sci.data,i,j)=hardset; Pix(rsz.sci.data,i,j)=hardset; Pix(raz.sci.data,i,j)=hardset; Pix(rsc.sci.data,i,j)=hardset; Pix(rzc.sci.data,i,j)=hardset; Pix(chg.sci.data,i,j)=hardset; } } /* SAVE A COPY OF THE RAW IMAGE FOR LATER */ makesciRAZ(&cd,&ab,&raw); /***SUBTRACT THE CTE BIAS FROM BOTH CHIPS IN PLACE***/ if (doCteBias(&wf3,&cd)){ freeSingleGroup(&cd); return(status); } if (doCteBias(&wf3,&ab)){ freeSingleGroup(&ab); return(status); } /*CONVERT TO RAZ FORMAT AND CORRECT FOR GAIN*/ if (raw2raz(&wf3, &cd, &ab, &raz)) return (status); /***CALCULATE THE SMOOTH READNOISE IMAGE***/ trlmessage("CTE: Calculating smooth readnoise image"); /***CREATE THE NOISE MITIGATION MODEL ***/ if (cte_pars.noise_mit == 0) { if (raz2rsz(&wf3, &raz, &rsz, cte_pars.rn_amp, max_threads)) return (status); } else { trlmessage("Only noise model 0 implemented!"); return (status=ERROR_RETURN); } /***CONVERT THE READNOISE SMNOOTHED IMAGE TO RSC IMAGE THIS IS WHERE THE CTE GETS CALCULATED ***/ if (rsz2rsc(&wf3, &rsz, &rsc, &cte_pars)) return (status); /*** SAVE USEFULL HEADER INFORMATION ***/ if (cteHistory (&wf3, cd.globalhdr)) return (status); /*** CREATE THE FINAL CTE CORRECTED IMAGE, PUT IT BACK INTO ORIGNAL RAW FORMAT***/ for (i=0;i<RAZ_COLS;i++){ for(j=0; j<RAZ_ROWS; j++){ Pix(chg.sci.data,i,j) = (Pix(rsc.sci.data,i,j) - Pix(rsz.sci.data,i,j))/wf3.ccdgain; Pix(rzc.sci.data,i,j) = Pix(raw.sci.data,i,j) + Pix(chg.sci.data,i,j); } } /*BACK TO NORMAL FORMATTING*/ undosciRAZ(&cd,&ab,&rzc); /*UPDATE THE OUTPUT HEADER ONE FINAL TIME*/ PutKeyDbl(cd.globalhdr, "PCTEFRAC", cte_pars.scale_frac,"CTE scaling fraction based on expstart"); trlmessage("PCTEFRAC saved to header"); /*SAVE THE NEW RAW FILE WITH UPDATED SCIENCE ARRAYS AND PRIMARY HEADER TO RAC*/ putSingleGroup(output,cd.group_num, &cd,0); putSingleGroup(output,ab.group_num, &ab,0); /** CLEAN UP **/ freeSingleGroup(&rzc); freeSingleGroup(&rsc); freeSingleGroup(&chg); freeSingleGroup(&raz); freeSingleGroup(&rsz); freeSingleGroup(&raw); time_spent = ((double) clock()- begin +0.0) / CLOCKS_PER_SEC; if (verbose){ sprintf(MsgText,"CTE run time: %.2f(s) with %i procs/threads\n",time_spent,max_threads); trlmessage(MsgText); } PrSwitch("pctecorr", COMPLETE); if(wf3.printtime) TimeStamp("PCTECORR Finished",wf3.rootname); return (status); }