예제 #1
0
파일: acssum.c 프로젝트: jhunkeler/hstcal
static int SumGrps (AcsSumInfo *acs, char *mtype) {

    extern int status;
    SingleGroup x;                /* first imset */
    SingleGroupLine y;            /* line from Nth imset */
    double exptime;                /* exposure time of current image */
    double sumexptime = 0.;        /* accumulated exposure time */
    char *message;                 /* for printtime info */
    int extver;                    /* imset number */
    int i;                    /* counter for current image */
    int chip, ychip;            /*Chip being summed */
    int extchip;            /* Extension of chip being summed */
    int line;                /* Line of chip being summed */
    char        uroot[CHAR_FNAME_LENGTH];   /* Upper case version of rootname */

    int doStat (SingleGroup *, short);
    void TimeStamp (char *, char *);
    void PrGrpBegin (char *, int);
    void PrGrpEnd (char *, int);
    void PrSwitch (char *, int);
    void UCalVer (Hdr *);
    void UFilename (char *, Hdr *);
    void UMemType (char *, Hdr *);
    void UExpname (char *, Hdr *);
    int DetCCDChip (char *, int, int, int *);
    void    UpperAll (char *, char *, int);

    int GetKeyInt (Hdr *, char *, int, int, int *);
    int GetKeyDbl (Hdr *, char *, int, double, double *);
    int PutKeyStr (Hdr *, char *, char *, char *);

    initSingleGroup (&x);
    initSingleGroupLine (&y);

    if (acs->printtime) {
        if ((message = calloc (CHAR_LINE_LENGTH+1, sizeof (char))) == NULL)
            return (status = OUT_OF_MEMORY);
    }

    for (extver = 1;  extver <= acs->nimsets;  extver++) {

        PrGrpBegin ("imset", extver);

        getSingleGroup (acs->input[0], extver, &x);
        if (hstio_err())
            return (status = OPEN_FAILED);
        if (acs->printtime)
            TimeStamp ("first imset read", acs->input[0]);

        /* get from x */
        if (GetKeyInt (&x.sci.hdr, "CCDCHIP", USE_DEFAULT, 1, &chip))
            return (status);
        if (GetKeyDbl (x.globalhdr, "EXPEND", NO_DEFAULT, 0., &acs->expend))
            return (status);

        sumexptime = acs->exptime;

        /* Square the errors to convert to variance. */
        SquareErr (&x);                /* operate on x */

        /* For each imset/extver, loop over all images */
        for (i = 1; i < acs->nimages; i++) {

            /* Determine which extension corresponds to desired chip
            ** for the remainder of the images.
            */
            extchip = 0;

            if (DetCCDChip(acs->input[i], chip, acs->nimsets, &extchip) ) {
                return (status);
            }

            /* Get the first line of bias image data. */
            openSingleGroupLine (acs->input[i], extchip, &y);
            if (hstio_err())
                return (status = OPEN_FAILED);

            /* Update exposure time info. */
            /* get from y */

            if (GetKeyInt (&y.sci.hdr, "CCDCHIP", USE_DEFAULT, 1, &ychip))
                return (status);
            if (GetKeyDbl (y.globalhdr, "EXPTIME", NO_DEFAULT, 0., &exptime))
                return (status);
            if (GetKeyDbl (y.globalhdr, "EXPEND", NO_DEFAULT, 0., &acs->expend))
                return (status);

            sumexptime += exptime;

            /*Loop over lines in each subsequent image */
            for (line = 0; line < x.sci.data.ny; line++) {
                status = getSingleGroupLine (acs->input[i], line, &y);
                if (status) {
                    sprintf(MsgText,"Could not read line %d from image %d.",line+1,i+1);
                    trlerror(MsgText);
                    return (status = OPEN_FAILED);
                }

                SquareErrLine (&y);                /* operate on y */

                /* Add current imset to sum (i.e. add y to x).  This differs
                    from add2d in that RptSum adds variances, rather than
                    adding errors in quadrature.
                */
                if (RptSumLine (&x, line, &y))
                    return (status);

            } /*End loop over lines */

            if (acs->printtime) {
                if (i == 1)
                    strcpy (message, "1st imset added");
                else if (i == 2)
                    strcpy (message, "2nd imset added");
                else if (i == 3)
                    strcpy (message, "3rd imset added");
                else
                    sprintf (message, "%dth imset added", i);

                TimeStamp (message, acs->input[i]);
            }

            closeSingleGroupLine (&y);
        } /* End loop over images */

        freeSingleGroupLine (&y);

        /* Take the square root of variance to convert back to errors. */
        SqrtErr (&x);

        /* Compute statistics and update keywords in output headers. */
        trlmessage ("\n");
        if (doStat (&x, acs->sdqflags))
        return (status);
        if (acs->printtime)
            TimeStamp ("Image statistics computed", acs->rootname);
        /* Update header info in output. */
        if (PutSumHdrInfo (&x, sumexptime, acs->expend, acs->nimages, acs->nimsets))
            return (status);

        /* Update CAL_VER and FILENAME, then write output file.
            EXPNAME values modified for all extensions in a SingleGroup.
                    WJH 7 July 1999
        */
        UCalVer (x.globalhdr);
        UFilename (acs->output, x.globalhdr);
        UMemType (mtype, x.globalhdr);
        UExpname (acs->rootname, &x.sci.hdr);
        UExpname (acs->rootname, &x.err.hdr);
        UExpname (acs->rootname, &x.dq.hdr);
        UpperAll (acs->rootname, uroot, strlen(acs->rootname)+1 );

        PutKeyStr (x.globalhdr, "ROOTNAME", uroot,"Rootname of the observation set");

        putSingleGroup (acs->output, extver, &x, 0);
        if (hstio_err())
                return (status = 1001);
        freeSingleGroup (&x);

        PrGrpEnd ("imset", extver);

        if (acs->printtime)
            TimeStamp ("Output written to disk", acs->rootname);
    } /* End loop over imsets */

    if (acs->printtime)
        free (message);
    return (status);
}
예제 #2
0
파일: sink.c 프로젝트: sosey/hstcal
int SinkDetect(WF3Info *wf3, SingleGroup *x){

    extern int status;
    int i,j, jj;
    short dqval=0;
    float scipix; /*to save the value of the science pixel*/
    float refdate=50000.;
    int keep_going=1;
    
    sprintf(MsgText,"\nPerforming SINK pixel detection for imset %i",x->group_num);
    trlmessage(MsgText);
    

    /*THE SCIENCE IMAGE*/
    SingleGroup raz; /*quad rotated image to work with*/    

    /* INIT THE SCIENCE INPUT  */
    initSingleGroup (&raz);
    allocSingleGroup (&raz,RAZ_COLS/2, RAZ_ROWS);
        
    /*CONVERT DQ DATA TO RAZ FORMAT FOR SCIENCE FILE*/
    makedqRAZ(x, &raz);
    makeSciSingleRAZ(x, &raz);

	/* GET THE SINK FILE REFERENCE IMAGE FROM SINKFILE AND INITIALIZE */
    FloatHdrData sinkref;
    initFloatHdrData(&sinkref);
    getFloatHD(wf3->sink.name,"SCI",x->group_num,&sinkref);
                 
    /*NOW TURN THE SINK REFERENCE IMAGES INTO RAZ FORMAT*/
    FloatTwoDArray sinkraz;    
    initFloatData(&sinkraz); /*float 2d arrays*/
    allocFloatData(&sinkraz,RAZ_COLS/2, RAZ_ROWS);     

    makeFloatRaz(&sinkref.data,&sinkraz,x->group_num);

       
    /*THE MJD OF THE SCIENCE EXPOSURE IS THE COMPARISON DATE
     THE FOLLOWING TRANSLATION TAKEN FROM ISR WFC3-2014-22.PDF */
    
    scipix=0.;
    for (i=0;i<(RAZ_COLS/2);i++){
        for (j=0; j<RAZ_ROWS; j++){
        
            if (  (PPix(&sinkraz,i,j) > refdate)  &&  ( wf3->expstart > PPix(&sinkraz,i,j))  ){
                keep_going=1;
                
                /*FLAG THE PRIMARY SINK PIXEL*/
                dqval = TRAP | DQPix (raz.dq.data, i, j);
                DQSetPix (raz.dq.data, i, j, dqval);
                scipix = Pix(raz.sci.data,i,j);
                
                /*FLAG THE DOWNSTREAM PIXEL*/
                if (PPix(&sinkraz,i,j-1) < 0 ){
                    dqval = TRAP | DQPix (raz.dq.data, i, j-1);
                    DQSetPix (raz.dq.data, i, j-1, dqval);
                }

                /*FLAG THE UPSTREAM PIXELS*/
                for (jj=j+1; jj<RAZ_ROWS; jj++){
                    if ((int) PPix(&sinkraz,i,jj) == 0)
                        keep_going=0;
                    if ( PPix(&sinkraz,i,jj) > refdate)
                        keep_going=0;
                    if ( 0. < PPix(&sinkraz,i,jj) &&  PPix(&sinkraz,i,jj) < 1000. && keep_going){
                        if (scipix <= PPix(&sinkraz,i,jj) ){
                           dqval = TRAP | DQPix (raz.dq.data, i, jj);
                           DQSetPix (raz.dq.data, i, jj, dqval);
                        }                
                    } else {
                        keep_going=0;
                    }
                }                
            } /*end if*/ 
        } /*end j*/
    }/*end i*/   

    
    /*format the dq data back to expected orientation*/
    undodqRAZ(x,&raz);

    freeSingleGroup(&raz);
    freeFloatData(&sinkraz);
    freeFloatHdrData(&sinkref);
    trlmessage("Sink pixel flagging complete");
    return(status);
}
예제 #3
0
파일: doflat.c 프로젝트: jhunkeler/hstcal
int doFlat (StisInfo1 *sts, SingleGroup *x) {

/* arguments:
StisInfo1 *sts     i: calibration switches, etc
SingleGroup *x    io: image to be calibrated; written to in-place
*/

	int status;

	SingleGroup w, y, z;	/* scratch space */
	float *ds;		/* Doppler smearing array */
	int nds;		/* size of ds */
	int d0;			/* index in ds of Doppler = 0 */
	int border;		/* = doppmag, unless obsmode = time-tag */
	int extver = 1;		/* get this group from flat field images */
	int rx, ry;		/* for binning dark down to size of x */
	int x0, y0;		/* offsets of sci image */
	int same_size;		/* true if no binning of ref image required */
	int high_res;		/* true if high-res pixels in dispersion dir */
	int avg = 1;		/* bin2d should average within each bin */
	int nx, ny;		/* how large to make y for lfltfile */
	int dummy;

	int FindBin (StisInfo1 *, SingleGroup *, SingleGroup *,
		int *, int *, int *, int *, int *, int *);
	int MakeDopp (double, double, double, double, double, int,
		float *, int *, int *);
	int DoppConv (SingleGroup *, int, float *, int, int);

	initSingleGroup (&w);
	initSingleGroup (&y);
	initSingleGroup (&z);

	/* pixel-to-pixel flat */
	if (sts->pfltcorr == PERFORM) {
	    getSingleGroup (sts->pflt.name, extver, &y);
	    if (hstio_err())
		return (OPEN_FAILED);
	}

	/* delta flat */
	if (sts->dfltcorr == PERFORM) {
	    if (sts->pfltcorr == PERFORM) {
		getSingleGroup (sts->dflt.name, extver, &z);
		if (y.sci.data.nx != z.sci.data.nx ||
		    y.sci.data.ny != z.sci.data.ny) {
		    printf (
	"ERROR    Pixel-to-pixel flat and delta flat are not the same size.\n");
		    return (SIZE_MISMATCH);
		}
		if ((status = mult2d (&y, &z)))		/* y is the product */
		    return (status);
		freeSingleGroup (&z);
	    } else {
		getSingleGroup (sts->dflt.name, extver, &y);
	    }
	    if (hstio_err())
		return (OPEN_FAILED);
	}

	/* low-order flat */
	if (sts->lfltcorr == PERFORM) {

	    /* Get lflt into a scratch area because lflt is smaller than y. */

	    if (sts->pfltcorr == PERFORM || sts->dfltcorr == PERFORM) {

		/* This is the normal case; we already have a product in y. */

		getSingleGroup (sts->lflt.name, extver, &w);
		if (hstio_err())
		    return (OPEN_FAILED);

		allocSingleGroup (&z, y.sci.data.nx, y.sci.data.ny, True);
		if (hstio_err())
		    return (ALLOCATION_PROBLEM);

		/* Resample w to z by linear interpolation. */
		if ((status = unbin2d (&w, &z))) /* unbin w --> z */
		    return (status);
		freeSingleGroup (&w);		/* we won't need w again */

		if ((status = mult2d (&y, &z))) /* y is the product */
		    return (status);
		freeSingleGroup (&z);

	    } else {

		/* We have neither a pixel-to-pixel flat nor a delta flat. */

		getSingleGroup (sts->lflt.name, extver, &z);

		/* figure out how much to expand the low-order flat. */
		FindBin (sts, x, &z, &dummy, &dummy, &rx, &ry, &dummy, &dummy);
		status = 0;		/* ignore status = REF_TOO_SMALL */

		/* Create y.  We don't need to assign any initial values
		   because y is strictly output from unbin2d.
		*/
		nx = rx * z.sci.data.nx;
		ny = ry * z.sci.data.ny;
		allocSingleGroup (&y, nx, ny, True);
		if (hstio_err())
		    return (ALLOCATION_PROBLEM);

		if ((status = unbin2d (&z, &y))) /* unbin z --> y */
		    return (status);
		freeSingleGroup (&z);
	    }
	}

	/* Now y contains the product of (up to) three flats. */

	/* Compare binning of science image and product of flat fields;
	   get same_size and high_res flags, and get info about binning
	   and offset for use by bin2d.
	*/
	if ((status = FindBin (sts, x, &y,
                               &same_size, &high_res, &rx, &ry, &x0, &y0)))
	    return (status);

	/* Do we need to do Doppler convolution? */
	if (sts->doppcorr == PERFORM) {

	    if (!high_res) {
		printf (
	"ERROR    Doppler convolution (DOPPCORR) was specified, \\\n");
		printf (
	"ERROR    but the flat fields are binned to low-res pixels.\n");
		return (SIZE_MISMATCH);
	    }

	    /* Allocate space for the Doppler smearing array, making it
		larger than we will need.  The actual size nds will be
		updated by MakeDopp.
	    */
	    nds = 2 * (sts->doppmag + 1) + 21;
	    ds = (float *) calloc (nds, sizeof (float));

	    if ((status = MakeDopp (sts->doppzero, sts->doppmag, sts->orbitper,
                                    sts->expstart, sts->exptime, sts->dispsign,
                                    ds, &nds, &d0)))
		return (status);

	    /* Convolve y with the Doppler smearing function. */
	    if (strcmp (sts->obsmode, "TIME-TAG") == 0)
		border = 0;
	    else
		border = NINT(sts->doppmag);
	    if ((status = DoppConv (&y, border, ds, nds, d0)))
		return (status);

	    free (ds);
	}

	/* Now we've got the complete flat field in y, convolved with
	   the Doppler smearing function if necessary.  Divide x by y.
	*/

	if (same_size) {

	    /* No binning required. */

	    if ((status = div2d (x, &y))) {
		printf ("ERROR    (doFlat) size mismatch\n");
		return (status);
	    }
	    freeSingleGroup (&y);

	} else {

	    /* Bin the flat field down to the actual size of x. */

	    allocSingleGroup (&z, x->sci.data.nx, x->sci.data.ny, True);
	    if ((status = bin2d (&y, x0, y0, rx, ry, avg, &z))) {
		printf ("ERROR    (doFlat) size mismatch\n");
		return (status);
	    }
	    freeSingleGroup (&y);		/* done with y */
	    if ((status = div2d (x, &z)))
		return (status);
	    freeSingleGroup (&z);		/* done with z */
	}

	return (0);
}
예제 #4
0
파일: acsrej_do.c 프로젝트: pllim/hstcal
/*  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);
}
예제 #5
0
파일: wf3cte.c 프로젝트: sosey/hstcal
int inverse_cte_blur(SingleGroup *rsz, SingleGroup *rsc, SingleGroup *fff, CTEParams *cte, int verbose, double expstart){
    
    extern int status;
        
    /*looping vars*/
    int NREDO, REDO;
    int NITINV, NITCTE; 
    int i;
    int j,jj;
    double dmod;
    int jmax;
    float hardset=0.0f;
    
    double cte_ff; /*cte scaling based on observation date*/
    double setdbl=0.0;
    
    /*DEFINE TO MAKE PRIVATE IN PARALLEL RUN*/    
    double *pix_obsd=&setdbl;   
    double *pix_modl=&setdbl;      
    double *pix_curr=&setdbl;   
    double *pix_init=&setdbl;   
    double *pix_read=&setdbl;   
    double *pix_ctef=&setdbl;   
    
    /*STARTING DEFAULTS*/
    NITINV=1;
    NITCTE=1;
    cte_ff=0.0;
    jmax=0;
    dmod=0.0;
    
    /*LOCAL IMAGES TO PLAY WITH, THEY WILL REPLACE THE INPUTS*/
    SingleGroup rz; /*pixz_raz*/
    initSingleGroup(&rz);
    allocSingleGroup(&rz, RAZ_COLS, RAZ_ROWS);
    
    SingleGroup rc; /*pixz_rac*/
    initSingleGroup(&rc);
    allocSingleGroup(&rc, RAZ_COLS, RAZ_ROWS);
    
    SingleGroup pixz_fff; /*pixz_fff*/
    initSingleGroup(&pixz_fff);
    allocSingleGroup(&pixz_fff, RAZ_COLS, RAZ_ROWS);
        
    for (i=0;i<RAZ_COLS;i++){ 
        for(j=0;j<RAZ_ROWS;j++){ 
            Pix(rc.sci.data,i,j)=hardset;
            Pix(rz.sci.data,i,j)=hardset;
            Pix(pixz_fff.sci.data,i,j)=hardset;
        }
    }            
        
        
    /*USE EXPSTART YYYY-MM-DD TO DETERMINE THE CTE SCALING
    APPROPRIATE FOR THE GIVEN DATE. WFC3/UVIS WAS
    INSTALLED AROUND MAY 11,2009 AND THE MODEL WAS
    CONSTRUCTED TO BE VALID AROUND SEP 3, 2012, A LITTLE
    OVER 3 YEARS AFTER INSTALLATION*/

    cte_ff=  (expstart - cte->cte_date0)/ (cte->cte_date1 - cte->cte_date0);    
    cte->scale_frac=cte_ff;   /*save to param structure for header update*/ 
    
    if(verbose){
        sprintf(MsgText,"CTE_FF (scaling fraction by date) = %g",cte_ff);
        trlmessage(MsgText);
    }
    
    /*SET UP THE SCALING ARRAY WITH INPUT DATA*/
    for (i=0; i<RAZ_COLS; i++){
        for (j=0; j< RAZ_ROWS; j++){
            Pix(rz.sci.data,i,j) = Pix(rsz->sci.data,i,j);
            Pix(pixz_fff.sci.data,i,j) =  cte_ff * Pix(fff->sci.data,i,j);
        }          
    }
            
  
    #pragma omp parallel for schedule (dynamic,1) \
        private(dmod,i,j,jj,jmax,REDO,NREDO, \
          pix_obsd,pix_modl,pix_curr,pix_init,\
          pix_read,pix_ctef,NITINV,NITCTE)\
        shared(rc,rz,cte,pixz_fff)
        
    for (i=0; i< RAZ_COLS; i++){           
       
       pix_obsd = (double *) calloc(RAZ_ROWS, sizeof(double));   
       pix_modl = (double *) calloc(RAZ_ROWS, sizeof(double));   
       pix_curr = (double *) calloc(RAZ_ROWS, sizeof(double));   
       pix_init = (double *) calloc(RAZ_ROWS, sizeof(double));   
       pix_read = (double *) calloc(RAZ_ROWS, sizeof(double));   
       pix_ctef = (double *) calloc(RAZ_ROWS, sizeof(double));   
    
        /*HORIZONTAL PRE/POST SCAN POPULATION */
        for (j=0; j< RAZ_ROWS; j++){
            pix_obsd[j] = Pix(rz.sci.data,i,j); /*starts as input RAZ*/
        }
        
        NREDO=0; /*START OUT NOT NEEDING TO MITIGATE CRS*/
        REDO=0; /*FALSE*/
        do { /*replacing goto 9999*/
            /*STARTING WITH THE OBSERVED IMAGE AS MODEL, ADOPT THE SCALING FOR THIS COLUMN*/
            for (j=0; j<RAZ_ROWS; j++){
                pix_modl[j] =  Pix(rz.sci.data,i,j);
                pix_ctef[j] =  Pix(pixz_fff.sci.data,i,j);     
            }
            /*START WITH THE INPUT ARRAY BEING THE LAST OUTPUT
              IF WE'VE CR-RESCALED, THEN IMPLEMENT CTEF*/
            for (NITINV=1; NITINV<=cte->n_forward; NITINV++){
                for (j=0; j<RAZ_ROWS; j++){
                    pix_curr[j]=pix_modl[j];
                    pix_read[j]=pix_modl[j];
                    pix_ctef[j]=Pix(pixz_fff.sci.data,i,j);
                 }
                                  
                /*TAKE EACH PIXEL DOWN THE DETECTOR IN NCTENPAR=7*/
                for (NITCTE=1; NITCTE<=cte->n_par; NITCTE++){
                    sim_colreadout_l(pix_curr, pix_read, pix_ctef, cte);
                                      
                    /*COPY THE JUST UPDATED READ OUT IMAGE INTO THE INPUT IMAGE*/
                    for (j=0; j< RAZ_ROWS; j++){
                        pix_curr[j]=pix_read[j];
                    }
                } /* end NITCTE */
                                
                /*DAMPEN THE ADJUSTMENT IF IT IS CLOSE TO THE READNOISE, THIS IS
                  AN ADDITIONAL AID IN MITIGATING THE IMPACT OF READNOISE*/
                for (j=0; j< RAZ_ROWS; j++){
                    dmod =  (pix_obsd[j] - pix_read[j]);
                    if (NITINV < cte->n_forward){ 
                        dmod *= (dmod*dmod) /((dmod*dmod) + (cte->rn_amp * cte->rn_amp));
                    }
                    pix_modl[j] += dmod; /*dampen each pixel as the best is determined*/
                }
            } /*NITINV end*/

            /*LOOK FOR AND DOWNSCALE THE CTE MODEL IF WE FIND
            THE TELL-TALE SIGN OF READOUT CRS BEING OVERSUBTRACTED;
            IF WE FIND ANY THEN GO BACK UP AND RERUN THIS COLUMN
            
            
            THE WFC3 UVIS MODEL SEARCHES FOR OVERSUBTRACTED TRAILS.
            WHICH ARE  DEFINED AS EITHER:  
            
            - A SINGLE PIXEL VALUE BELOW -10E-
            - TWO CONSECUTIVE PIXELS TOTALING -12 E-
            - THREE TOTALLING -15 E-
 
             WHEN WE DETECT SUCH AN OVER-SUBTRACTED TAIL, WE ITERATIVELY REDUCE
             THE LOCAL CTE SCALING BY 25% UNTIL THE TRAIL IS
             NO LONGER NEGATIVE  THIS DOES NOT IDENTIFY ALL READOUT-CRS, BUT IT DOES
             DEAL WITH MANY OF THEM. FOR IMAGES THAT HAVE BACKGROUND GREAT THAN 10 OR SO,
             THIS WILL STILL END UP OVERSUBTRACTING CRS A BIT, SINCE WE ALLOW
             THEIR TRAILS TO BE SUBTRACTED DOWN TO -10 RATHER THAN 0.
            
            */
            if (cte->fix_rocr) {
                for (j=10; j< RAZ_ROWS-2; j++){                        
                    if (  (( cte->thresh > pix_modl[j] ) && 
                           ( cte->thresh > (pix_modl[j] - pix_obsd[j]))) ||

                          (((pix_modl[j] + pix_modl[j+1]) < -12.) &&
                           (pix_modl[j] + pix_modl[j+1] - pix_obsd[j] - pix_obsd[j+1] < -12.)) ||

                          (((pix_modl[j] + pix_modl[j+1] + pix_modl[j+2]) < -15.) &&
                           ((pix_modl[j] + pix_modl[j+1] + pix_modl[j+2] -pix_obsd[j] - 
                                 pix_obsd[j+1] - pix_obsd[j+2]) <-15.))  ){
                                 
                            jmax=j;
                            
                            /*GO DOWNSTREAM AND LOOK FOR THE OFFENDING CR*/
                            for (jj=j-10; jj<=j;jj++){
                                if ( (pix_modl[jj] - pix_obsd[jj]) > 
                                        (pix_modl[jmax] - pix_obsd[jmax]) ) {
                                        jmax=jj;
                                }   
                            }
                            /* DOWNGRADE THE CR'S SCALING AND ALSO FOR THOSE
                                BETWEEN THE OVERSUBTRACTED PIXEL AND IT*/
                            for (jj=jmax; jj<=j;jj++){
                                Pix(pixz_fff.sci.data,i,jj) *= 0.75;
                            }
                            REDO=1; /*TRUE*/
                    } /*end if*/
                } /*end for  j*/
            }/*end fix cr*/
            
            if (REDO) NREDO +=1;
            if (NREDO == 5)  REDO=0; /*stop*/
        } while (REDO); /*replacing goto 9999*/
        
        #pragma omp critical (cte)        
        for (j=0; j< RAZ_ROWS; j++){
             Pix(rc.sci.data,i,j)= pix_modl[j]; 
        }         

    free(pix_obsd);
    free(pix_modl);
    free(pix_curr);
    free(pix_init);
    free(pix_read);
    free(pix_ctef);
              
    } /*end i*/                 



    for (i=0; i< RAZ_COLS; i++){
        for (j=0; j< RAZ_ROWS; j++){
            Pix(rsz->sci.data,i,j) = Pix(rz.sci.data,i,j);
            Pix(rsc->sci.data,i,j) = Pix(rc.sci.data,i,j);
            Pix(fff->sci.data,i,j) = Pix(pixz_fff.sci.data,i,j);
        }
    }
    
    freeSingleGroup(&rz); 
    freeSingleGroup(&rc);
    freeSingleGroup(&pixz_fff);
             
    return(status);
}
예제 #6
0
파일: wf3cte.c 프로젝트: sosey/hstcal
/*** THIS ROUTINE PERFORMS THE CTE CORRECTIONS 
     rsz is the readnoise smoothed image
     rsc is the output image
     rac = raw + ((rsc-rsz) / gain )
     
***/
int rsz2rsc(WF3Info *wf3, SingleGroup *rsz, SingleGroup *rsc, CTEParams *cte) {

    extern int status;
    
    int i,j;
    double cte_i=0.0;
    double cte_j=0.0;
    double ro=0;
    int io=0;
    double ff_by_col[RAZ_COLS][4];
    float hardset=0.0;
    
    /*These are already in the parameter structure
    int     Ws              the number of traps < 999999, taken from pctetab read 
    int     q_w[TRAPS];     the run of charge with level  cte->qlevq_data[]
    float   dpde_w[TRAPS];  the run of charge loss with level cte->dpdew_data[]
    
    float   rprof_wt[TRAPS][100]; the emission probability as fn of downhill pixel, TRAPS=999
    float   cprof_wt[TRAPS][100]; the cumulative probability cprof_t( 1)  = 1. - rprof_t(1)
    */
        
    SingleGroup pixz_fff;
    initSingleGroup(&pixz_fff);
    allocSingleGroup(&pixz_fff, RAZ_COLS, RAZ_ROWS);
    
    for(i=0; i<RAZ_COLS;i++){
        for(j=0; j<RAZ_ROWS; j++){
            Pix(pixz_fff.sci.data,i,j)=hardset;
        }
    }
    
    /*FOR REFERENCE TO JAYS CODE, FF_BY_COL IS WHAT'S IN THE SCALE BY COLUMN
    
    int   iz_data[RAZ_ROWS];  column number in raz format
    double scale512[RAZ_ROWS];      scaling appropriate at row 512 
    double scale1024[RAZ_ROWS];     scaling appropriate at row 1024
    double scale1536[RAZ_ROWS];     scaling appropriate at row 1536
    double scale2048[RAZ_ROWS];     scaling appropriate at row 2048
    */
    
    /*SCALE BY 1 UNLESS THE PCTETAB SAYS OTHERWISE, I IS THE PACKET NUM
      THIS IS A SAFETY LOOP INCASE NOT ALL THE COLUMNS ARE POPULATED
      IN THE REFERENCE FILE*/
    for (i=0; i<RAZ_COLS;i++){
        ff_by_col[i][0]=1.;
        ff_by_col[i][1]=1.;
        ff_by_col[i][2]=1.;
        ff_by_col[i][3]=1.;
    }
        
    for (i=0;i<RAZ_COLS;i++){
        j= cte->iz_data[i]; /*which column to scale*/
        ff_by_col[j][0]=cte->scale512[i];
        ff_by_col[j][1]=cte->scale1024[i];
        ff_by_col[j][2]=cte->scale1536[i];
        ff_by_col[j][3]=cte->scale2048[i];
    }
        
    
    
    /*CALCULATE THE CTE CORRECTION FOR EVERY PIXEL
     Index is figured on the final size of the image
     not the current size
    */
    for (i=0; i<RAZ_COLS; i++){
        for (j=0;j<RAZ_ROWS; j++){
            ro = j/512.0; /*ro can be zero, it's an index*/
            if (ro <0 ) ro=0.;
            if (ro > 2.999) ro=2.999; /*only 4 quads, 0 to 3*/
            io = (int) floor(ro); /*force truncation towards 0 for pos numbers*/
            cte_j= (j+1) / 2048.0; 
            cte_i= ff_by_col[i][io] + (ff_by_col[i][io+1] -ff_by_col[i][io]) * (ro-io);
            Pix(pixz_fff.sci.data,i,j) =  (cte_i*cte_j);
        }
    }
    
    /*THIS IS RAZ2RAC_PAR IN JAYS CODE - MAIN CORRECTION LOOP IN HERE*/    
    inverse_cte_blur(rsz, rsc, &pixz_fff, cte, wf3->verbose,wf3->expstart);
    freeSingleGroup(&pixz_fff);
    return(status);
}
예제 #7
0
파일: wf3cte.c 프로젝트: sosey/hstcal
int raz2rsz(WF3Info *wf3, SingleGroup *raz, SingleGroup *rsz, double rnsig, int max_threads){
    /*
       This routine will read in a RAZ image and will output the smoothest
       image that is consistent with being the observed image plus readnoise. (RSZ image) 
       This is necessary because we want the CTE-correction algorithm to produce the smoothest
       possible reconstruction, consistent with the original image and the
       known readnoise.  This algorithm constructs a model that is smooth
       where the pixel-to-pixel variations can be thought of as being related
       to readnoise, but if the variations are too large, then it respects
       the pixel values.  Basically... it uses a 2-sigma threshold.

       This is strategy #1 in a two-pronged strategy to mitigate the readnoise
       amplification.  Strategy #2 will be to not iterate when the deblurring
       is less than the readnoise.

*/

    extern int status;
        
    int i, j, NIT; /*loop variables*/
    int imid;
    double dptr=0.0;
    double  rms=0.0;
    double  rmsu=0.0;
    double nrms=0.0;
    double nrmsu=0.0;
    float hardset=0.0f;
    double setdbl=0.0;

    /*1D ARRAYS FOR CENTRAL AND NEIGHBORING RAZ_COLS*/
    double obs_loc[3][RAZ_ROWS] ; 
    double rsz_loc[3][RAZ_ROWS] ;
        
    NIT=1;
    
    /*ALL ELEMENTS TO ZERO*/
    for(i=0;i<3;i++){
        for (j=0; j<RAZ_ROWS; j++){
            obs_loc[i][j]=setdbl;
            rsz_loc[i][j]=setdbl;
        }
    }
        
    /***INITIALIZE THE LOCAL IMAGE GROUPS***/
    SingleGroup rnz;
    initSingleGroup(&rnz);
    allocSingleGroup(&rnz, RAZ_COLS, RAZ_ROWS);
        
    SingleGroup zadj;
    initSingleGroup(&zadj);
    allocSingleGroup(&zadj, RAZ_COLS, RAZ_ROWS);  


    /*COPY THE RAZ IMAGE INTO THE RSZ OUTPUT IMAGE
      AND INITIALIZE THE OTHER IMAGES*/
    for(i=0;i<RAZ_COLS;i++){
        for (j=0;j<RAZ_ROWS;j++){
            Pix(rsz->sci.data,i,j) = Pix(raz->sci.data,i,j);
            Pix(rnz.sci.data,i,j) = hardset;
            Pix(zadj.sci.data,i,j) = hardset;
        }
    }
    

    /*THE RSZ IMAGE JUST GETS UPDATED AS THE RAZ IMAGE IN THIS CASE*/
    if (rnsig < 0.1){
        trlmessage("rnsig < 0.1, No read-noise mitigation needed");
        return(status); 
    }

    /*GO THROUGH THE ENTIRE IMAGE AND ADJUST PIXELS TO MAKE THEM
      SMOOTHER, BUT NOT SO MUCH THAT IT IS NOT CONSISTENT WITH
      READNOISE.  DO THIS IN BABY STEPS SO THAT EACH ITERATION
      DOES VERY LITTLE ADJUSTMENT AND INFORMATION CAN GET PROPAGATED
      DOWN THE LINE.
    */
             
    rms=setdbl;
    
    for(NIT=1; NIT<=100; NIT++){ 
        #pragma omp parallel for schedule(dynamic) \
           private(i,j,imid,obs_loc,rsz_loc,dptr)\
           shared(raz, rsz, rnsig,rms,nrms, zadj)        
        for(i=0; i<RAZ_COLS; i++){
            imid=i;

            /*RESET TO MIDDLE RAZ_COLS AT ENDPOINTS*/
            if (imid < 1)
                imid=1;
            if (imid == RAZ_COLS-1)
                imid = RAZ_COLS-2;

            /*COPY THE MIDDLE AND NEIGHBORING PIXELS FOR ANALYSIS*/    
            for(j=0; j<RAZ_ROWS; j++){
                obs_loc[0][j] = Pix(raz->sci.data,imid-1,j);
                obs_loc[1][j] = Pix(raz->sci.data,imid,j);
                obs_loc[2][j] = Pix(raz->sci.data,imid+1,j);

                rsz_loc[0][j] = Pix(rsz->sci.data,imid-1,j);
                rsz_loc[1][j] = Pix(rsz->sci.data,imid,j);
                rsz_loc[2][j] = Pix(rsz->sci.data,imid+1,j);
            }
            for (j=0; j<RAZ_ROWS; j++){  
                find_dadj(1+i-imid,j, obs_loc, rsz_loc, rnsig, &dptr);
                Pix(zadj.sci.data,i,j) = dptr;
            }
        } /*end the parallel for*/
     
            
        /*NOW GO OVER ALL THE RAZ_COLS AND RAZ_ROWS AGAIN TO SCALE THE PIXELS */
        for(i=0; i<RAZ_COLS;i++){
            for(j=0; j<RAZ_ROWS; j++){
                Pix(rsz->sci.data,i,j) +=  (Pix(zadj.sci.data,i,j)*0.75);
                Pix(rnz.sci.data,i,j) = (Pix(raz->sci.data,i,j) - Pix(rsz->sci.data,i,j));
            }                
        }
        
        rms=setdbl;
        nrms=setdbl;
               
       #pragma omp parallel for schedule(dynamic)\
        private(i,j,rmsu,nrmsu) \
        shared(raz,rsz,rms,rnsig,nrms)
       for(j=0; j<RAZ_ROWS; j++){
            nrmsu=setdbl;
            rmsu=setdbl;
            for(i = 0;i<RAZ_COLS; i++){
                if ( (fabs(Pix(raz->sci.data,i,j)) > 0.1) || 
                     (fabs(Pix(rsz->sci.data,i,j)) > 0.1) ){
                    rmsu  +=  ( Pix(rnz.sci.data,i,j) * Pix(rnz.sci.data,i,j) );
                    nrmsu += 1.0;
                }
            }
            #pragma omp critical (rms)
            {   rms  += rmsu;
                nrms += nrmsu;
            }
        }
        rms = sqrt(rms/nrms);
        
        /*epsilon type comparison*/
        if ( (rnsig-rms) < 0.00001) break; /*this exits the NIT for loop*/
     } /*end NIT*/
    
    freeSingleGroup(&zadj);
    freeSingleGroup(&rnz);
 
    return (status);
}
예제 #8
0
파일: wf3cte.c 프로젝트: sosey/hstcal
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);
}