Example #1
0
/*GetImageLineByProj:
	PRIVATE routine called by getLineByProj.
Has same semantics as getLineByProj.  Returns
zero-padded float array in out.
*/
void getImageLineByProj(double px,double py,int ns,image *im,float *out)
{
#define MIN(a,b) ((a)<(b) ? (a) : (b))

	register int x;
	int reqLine,reqSample;
	reqSample=(px-im->pStartX)/im->pDistX;
	reqLine=(py-im->pStartY)/im->pDistY;
	
	/*printf("Projection %f,%f corresponds to line %i, sample %i\n",
		px,py,reqLine,reqSample);*/
	
	if ((reqLine>=0) && (reqLine < im->ddr.nl))
	/*Line is in bounds, so we read it in and zero-fill the rest of the line.*/
	{
		int inSample,outSample,copySamples;
		
		if (reqSample>0)
		{
			inSample=reqSample;
			outSample=0;
		} else {
			inSample=0;
			outSample=-reqSample;
		}
		copySamples=MIN(ns-outSample,im->ddr.ns-inSample);
		getFloatLine(im->f,&im->ddr,reqLine,im->readBuf);
		for (x=0;x<outSample;x++)
			out[x]=0.0;
		for (x=0;x<copySamples;x++)
			out[x+outSample]=im->readBuf[x+inSample];
		for (x=outSample+copySamples;x<ns;x++)
			out[x]=0.0;
	}
	else /*Fill blank line.*/
		for (x=0;x<ns;x++)
			out[x]=0.0;
}
Example #2
0
int rej_init (IODescPtr ipsci[], IODescPtr ipdq[], clpar *par, int nimgs,
	      int dim_x, int dim_y, multiamp noise, multiamp gain, float efac[],
	      float skyval[], DataUnits bunit[], SingleGroup *sg, float *work) {

    extern int status;

    float  scale, val, raw, raw0, signal0;
    float  *buf;
    short  *bufdq;
    float  *exp2;
    int    i, j, n;
    int    dum;
    int    *npts, *ipts;
    float  noise2[NAMPS], rog2[NAMPS];
    float  gain2[NAMPS];
    float  nse[2], gn[2];
    int    ampx, ampy, detector, chip;
    int    k, p;
    short  dqpat;
    float  exp2n, expn;
    int    non_zero;
    Hdr    dqhdr;

    void ipiksrt (float [], int, int[]);
    void get_nsegn (int, int, int, int, float *, float*, float *, float *);

    /* -------------------------------- begin ------------------------------ */
    expn=0.0f;
    scale = par->scalense / 100.;
    ampx = gain.colx;
    ampy = gain.coly;
    detector = gain.detector;
    chip = gain.chip;
    dqpat = par->badinpdq;

    ipts = calloc (nimgs, sizeof(int));
    npts = calloc (dim_x, sizeof(int));
    buf = calloc (dim_x, sizeof(float));
    exp2 = (float *) calloc (nimgs, sizeof(float));
    bufdq = calloc (dim_x, sizeof(short));

    for (k = 0; k < NAMPS; k++) {
        gain2[k] = 0.;
        noise2[k] = 0.;
        /* Assumption: ALL images have the same noise/gain values */
        rog2[k] = SQ(noise.val[k]);
    }

    non_zero = 0;
    for (n = 0; n < nimgs; n++) {
        exp2[n] = SQ(efac[n]);
	if (efac[n] > 0.) non_zero++;
    }
    get_nsegn (detector, chip, ampx, ampy, gain.val, rog2, gain2, noise2); 

    /* Use the stack median to construct the initial average */
    if (strncmp(par->initgues, "median", 3) == 0) {
        for (j = 0; j < dim_y; j++) {
            memset (npts, 0, dim_x*sizeof(int));

            /* Set up the gain and noise values used for this line
	    ** in ALL images */
            if (j < ampy ) {
                gn[0] = gain2[AMP_C];
                gn[1] = gain2[AMP_D];
                nse[0] = noise2[AMP_C];
                nse[1] = noise2[AMP_D];
            } else {
                gn[0] = gain2[AMP_A];
                gn[1] = gain2[AMP_B];
                nse[0] = noise2[AMP_A];
                nse[1] = noise2[AMP_B];            
            }

            for (n = 0; n < nimgs; n++) {
                initHdr(&dqhdr);
                getHeader(ipdq[n],&dqhdr);
                getFloatLine (ipsci[n], j, buf);
                getShortLine (ipdq[n], j, bufdq);
                freeHdr(&dqhdr);

		/* Rescale SCI data, if necessary */
		if (bunit[n] == COUNTRATE) {
		    for (i = 0; i < dim_x; i++) {
			 buf[i] *= efac[n];
		    }
		}

                for (i = 0; i < dim_x; i++) {
		     if (efac[n] > 0.) {
                         /* Only use GOOD pixels to build initial image */
                         if ((bufdq[i] & dqpat) == OK) {
                             PIX(work,npts[i],i,nimgs) =
						(buf[i] - skyval[n]) / efac[n];
                             npts[i] += 1;
                         }
		     } else {
			 PIX(work,npts[i],i,nimgs) = 0.;
		     }
                }
            }
 
            for (i = 0; i < ampx; i++) {
                dum = npts[i];

                if (dum == 0)
                    Pix(sg->sci.data,i,j) = 0.0F;

                else {

		    /* Setup index array for sorting... */
		    for (p=0; p < nimgs; p++) ipts[p] = p;
		    /* Sort pixel stack and corresponding index array. */
                    ipiksrt (&PIX(work,0,i,nimgs), dum, ipts);

		    /* Use sorted index array to match proper exptimes to
		       selected pixels for use in ERR array calculation. */
                    if ((dum/2)*2 == dum) {
                        /* Even number of input images for this pixel */
                        Pix(sg->sci.data,i,j) = (PIX(work,dum/2-1,i,nimgs) +
						 PIX(work,dum/2,i,nimgs)) / 2.;
			expn = (exp2[ipts[dum/2-1]] + exp2[ipts[dum/2]]) / 2.;
                    } else {
			/* Odd number of input images for this pixel */
                        Pix(sg->sci.data,i,j) = PIX(work,dum/2,i,nimgs);
			expn = exp2[ipts[dum/2]];
		    }
                }
                
                raw0 = Pix(sg->sci.data,i,j);
		exp2n = (expn > 0.) ? expn : 1.;
                Pix(sg->err.data,i,j) = (nse[0]+ raw0/gn[0] + SQ(scale*raw0)) /
					exp2n;
            } /* End loop over FIRST AMP used on pixels in the line */
             
            for (i = ampx; i < dim_x; i++) {
                dum = npts[i];
                if (dum == 0)
                    Pix(sg->sci.data,i,j) = 0.0F;
                else {
		    for (p=0; p < nimgs; p++) ipts[p] = p;
                    ipiksrt (&PIX(work,0,i,nimgs), dum, ipts);
                    if ((dum/2)*2 == dum) {
                        /* Even number of input images for this pixel */
                        Pix(sg->sci.data,i,j) = (PIX(work,dum/2-1,i,nimgs) +
						 PIX(work,dum/2,i,nimgs)) / 2.;
			expn = (exp2[ipts[dum/2-1]] + exp2[ipts[dum/2]]) / 2.;
                    } else {
                        Pix(sg->sci.data,i,j) = PIX(work,dum/2,i,nimgs);
			expn = exp2[ipts[dum/2]];
		    }
                }
                
                raw0 = Pix(sg->sci.data,i,j);
		exp2n = (expn > 0.) ? expn : 1.;
                Pix(sg->err.data,i,j) = (nse[1]+ raw0/gn[1] + SQ(scale*raw0)) /
					exp2n;
            } /* End loop over SECOND AMP used on pixels in the line */
        } /* End loop over lines */

    } else {

        /* use the minimum to construct the initial average */
        if (strncmp(par->initgues, "minimum", 3) != 0) {
            sprintf (MsgText,"Invalid INITGUES value %s, reset it to 'minimum'",
		     par->initgues);
            trlwarn (MsgText);
            strcpy (par->initgues, "minimum");
        }

        for (n = 0; n < nimgs; n++) {
            initHdr(&dqhdr);
            getHeader(ipdq[n],&dqhdr);
            for (j = 0; j < dim_y; j++) { 
                /* Set up the gain and noise values used for this line
		** in ALL images */
                if (j < ampy ) {
                    gn[0] = gain2[AMP_C];
                    gn[1] = gain2[AMP_D];
                    nse[0] = noise2[AMP_C];
                    nse[1] = noise2[AMP_D];
                } else {
                    gn[0] = gain2[AMP_A];
                    gn[1] = gain2[AMP_B];
                    nse[0] = noise2[AMP_A];
                    nse[1] = noise2[AMP_B];            
                }

                getFloatLine (ipsci[n], j, buf);
		getShortLine (ipdq[n],  j, bufdq);

		/* Rescale SCI data, if necessary */
		if (bunit[n] == COUNTRATE) {
		    for (i = 0; i < dim_x; i++) {
			 buf[i] *= efac[n];
		    }
		}

                /* AMPS C and D */
                for (i = 0; i < ampx; i++) {
                    raw = buf[i];
                    raw0 = (raw > 0.)? raw : 0.;
		    signal0 = ((raw - skyval[n]) > 0.) ? (raw - skyval[n]) : 0.;

		    if (efac[n] > 0.) {
                        val = (raw - skyval[n]) / efac[n];
		    } else {
			val = 0.;
		    }
                    if ((n == 0) || (val < Pix(sg->sci.data,i,j)) ) {
			if ((bufdq[i] & dqpat) == OK && (efac[n] > 0.)) {
                             Pix(sg->sci.data,i,j) = val;
                             /*Pix(sg->err.data,i,j) =
			      (nse[0]+ raw0/gn[0] + SQ(scale*raw0)) / exp2[n];*/
			     Pix(sg->err.data,i,j) =
			    (nse[0] + raw0/gn[0] + SQ(scale*signal0)) / exp2[n];
			} else {
			     Pix(sg->sci.data,i,j) = 0.;
			     Pix(sg->err.data,i,j) = 0.;
			}
                    } 
                } /* End of loop over FIRST AMP for this line in each image */

                for (i = ampx; i < dim_x; i++) {
                    raw = buf[i];
                    raw0 = (raw > 0.)? raw : 0.;
		    signal0 = ((raw - skyval[n]) > 0.) ? (raw - skyval[n]) : 0.;

		    if (efac[n] > 0.) {
                        val = (raw - skyval[n]) / efac[n];
		    } else {
			val = 0.;
		    }
                    if ((n == 0) ||
		       (val<Pix(sg->sci.data,i,j) && ((bufdq[i]&dqpat)==OK))) {
                        Pix(sg->sci.data,i,j) = val;
			if (efac[n] > 0.) {
                            Pix(sg->err.data,i,j) = 
			     (nse[1]+ raw0/gn[1] + SQ(scale*signal0)) / exp2[n];
			} else {
			    Pix(sg->err.data,i,j) = 0.;
			}
                    } 
                } /* End of loop over SECOND AMP for this line in each image */

            } /* End of loop over lines in image (y) */
            freeHdr(&dqhdr);
        } /* End of loop over images in set */
    }

    /* free the memory */
    free (ipts);
    free (npts);
    free (buf);
    free (exp2);
    free (bufdq);

    return (status);
}
Example #3
0
/* acsrej_init -- get the initial average pixel values

  Description:
  ------------
  Get the initial average according to the specified scheme

  Date          Author          Description
  ----          ------          -----------
  22-Sep-1998   W.J. Hack       initial version, uses multiamp noise,gain
  20-Mar-2000   W.J. Hack       corrected problem with rog2, needed to be array
  15-Apr-2002   W.J. Hack       correctly zero'd out npts array, added
                                DQ checking for BOTH median and minimum images,
                                also added ERR array for median image.
  26-Aug-2002   J. Blakeslee    Modified threshhold for minimum to use SCALENSE
                                only with sky-subtracted pixels.
  01-Dec-2015   P.L. Lim        Calculations now entirely in electrons.
  13-Jan-2016   P.L. Lim        Removed variance init and cleaned up function.
*/
int acsrej_init (IODescPtr ipsci[], IODescPtr ipdq[], clpar *par, int nimgs,
                 int dim_x, int dim_y, float efac[], float skyval[],
                 SingleGroup *sg, float *work) {
    /*
      Parameters:

      ipsci   i: Array of pointers to SCI extension of the given EXTVER,
                 each pointer is an input image. Unit now in electrons.
      ipdq    i: Array of pointers to DQ extension of the given EXTVER,
                 each pointer is an input image.
      par     i: User specified parameters.
      nimgs   i: Number of input images.
      dim_x, dim_y  i: Image dimension taken from the first input image.
                       All images must have the same dimension.
      efac    i: Array of EXPTIME for each image. If all inputs have
                 EXPTIME=0 (all biases), then the values are all set to 1.
      skyval  i: Array of sky values for each input image.
                 Unit now in electrons.
      sg      o: Its "sci" component is the average image used for
                 comparison during CR rejection. Unit is e/s.
                 This is really the median or minimum depending on
                 "initgues" provided by the user.
      work    o: Intermediate result used to calculate sg but not used
                 outside this function.
    */
    extern int status;

    float     val, raw, dumf;
    int       i, j, n, p, dum;
    float     *buf;
    short     *bufdq;
    int       *npts, *ipts;
    short     dqpat;
    Hdr       dqhdr;

    void      ipiksrt (float [], int, int[]);

    /* -------------------------------- begin ------------------------------- */

    dqpat = par->badinpdq;

    ipts = calloc (nimgs, sizeof(int));
    npts = calloc (dim_x, sizeof(int));
    buf = calloc (dim_x, sizeof(float));
    bufdq = calloc (dim_x, sizeof(short));

    /* Use the stack median to construct the initial average. */
    if (strncmp(par->initgues, "median", 3) == 0) {
        for (j = 0; j < dim_y; j++) {
            memset (npts, 0, dim_x*sizeof(int));

            for (n = 0; n < nimgs; n++) {
                initHdr(&dqhdr);
                getHeader(ipdq[n], &dqhdr);
                getFloatLine (ipsci[n], j, buf);  /* electrons */
                getShortLine (ipdq[n], j, bufdq);
                freeHdr(&dqhdr);

                /* Only use GOOD pixels to build initial image.
                   work array is already initialized to zeroes in acsrej_do.c */
                if (efac[n] > 0.) {
                    for (i = 0; i < dim_x; i++) {
                        if ((bufdq[i] & dqpat) == OK) {
                            PIX(work, npts[i], i, nimgs) =
                                (buf[i] - skyval[n]) / efac[n];  /* e/s */
                            npts[i] += 1;
                        }
                    }
                }
            }  /* End of nimgs loop */

            /* ALL AMPS */
            for (i = 0; i < dim_x; i++) {
                dum = npts[i];  /* Number of good data points */
                if (dum == 0)
                    Pix(sg->sci.data, i, j) = 0.0F;
                else {
                    /* Setup index array for sorting... */
                    for (p=0; p < nimgs; p++) ipts[p] = p;
                    /* Sort pixel stack and corresponding index array. */
                    ipiksrt (&PIX(work, 0, i, nimgs), dum, ipts);
                     /* Even number of input images for this pixel */
                    if ((dum / 2) * 2 == dum) {
                        Pix(sg->sci.data, i, j) =
                            (PIX(work, dum / 2 - 1, i, nimgs) +
                             PIX(work, dum / 2, i, nimgs)) / 2.;
                    } else {
                        Pix(sg->sci.data, i, j) = PIX(work, dum / 2, i, nimgs);
                    }
                }
            } /* End loop over ALL AMPS used on pixels in the line */
        } /* End loop over lines */

    /* use the minimum to construct the initial average */
    } else {
        if (strncmp(par->initgues, "minimum", 3) != 0) {
            sprintf (MsgText,
                     "Invalid INITGUES value %s, reset it to 'minimum'",
                     par->initgues);
            trlwarn (MsgText);
            strcpy (par->initgues, "minimum");
        }

        for (n = 0; n < nimgs; n++) {
            initHdr(&dqhdr);
            getHeader(ipdq[n], &dqhdr);

            for (j = 0; j < dim_y; j++) {
                getFloatLine (ipsci[n], j, buf);  /* electrons */
                getShortLine (ipdq[n], j, bufdq);

                /* ALL AMPS */
                for (i = 0; i < dim_x; i++) {
                    raw = buf[i];  /* e */
                    dumf = raw - skyval[n];  /* e */

                    if (efac[n] > 0.) {
                        /* Can be negative */
                        val = dumf / efac[n];  /* e/s */
                    } else {
                        val = 0.;
                    }

                    if ( (n == 0) || (val < Pix(sg->sci.data, i, j)) ) {
                        /* If this pixel is bad in the first image,
                           then the min is automatically set to 0. As a
                           result, only negative val is going to be stored and
                           valid positive min is ignored.
                           SLIGHTLY BUGGY HERE??? */
                        if ((bufdq[i] & dqpat) == OK && (efac[n] > 0.)) {
                            Pix(sg->sci.data, i, j) = val;  /* e/s */
                        } else {
                            Pix(sg->sci.data, i, j) = 0.;
                        }
                    }
                } /* End of loop over ALL AMPS for this line in each image */
            } /* End of loop over lines in image (y) */

            freeHdr(&dqhdr);
        } /* End of loop over images in set */
    }

    /* free the memory */
    free (ipts);
    free (npts);
    free (buf);
    free (bufdq);

    return (status);
}
Example #4
0
void rej_sky (char *sky, IODescPtr ipsci[], IODescPtr ipdq[], int nimgs,
	      short badinpdq, float efac[], DataUnits bunit[], float skyval[]) {

/* Revision history:
**
** H. Bushouse	18-Jun-2002	Made bin width checking more robust. Also
**				allocate and free histogram for each image
**				(following CALACS changes).
** H. Bushouse	06-Dec-2007	Added calls to getHeader before each call to
**				getShortLine to prevent getShortLine from
**				crashing on null DQ arrays.
** H. Bushouse	22-May-2008	Avoid arithmetic overflow in binning
**				calculations.
** H. Bushouse	08-Oct-2008	Added capabilities for "mean" sky calculation
**				mode, using resistmean function.
** H. Bushouse	14-Dec-2011	Upgraded to rescale input data that are in
**				units of count rates. (PR 69969; Trac #814)
*/

    extern int status;

    int         *histgrm;   /* pointer to the histogram */
    int         nbins;      /* number of bins */
    int         min, max;
    float       data_min;
    float       hwidth;     /* histogram resolution */
    float       hmin;       /* minimum histogram value */
    int         i, k, h;
    float       *a;
    short       *b;
    int         line, npt;
    int         dimx, dimy;
    float       sum, mean;
    Hdr		dqhdr;

    Bool   mode, rmean;	    /* sky calculation mode flags */
    float *skyarr;	    /* pointer to sky values array */
    float  ssig, smin, smax; /* sky resistantmean values */

    float cr_mode (int *, int, float, float);
    int	  resistmean (float *, int, float, float *, float *, float *, float *);

    /* -------------------------------- begin ------------------------------- */

    nbins=0;
    min=0;
    max=0;
    hwidth=0.0f;
    hmin=0.0f;
    npt=0;
    histgrm=NULL;
    skyarr=NULL;

    /* decide what to do according to sky */
    if (strcmp (sky, "none") == 0) {
        for (k = 0; k < nimgs; ++k) {
            skyval[k] = 0.;
        }
        return;
    } else if (strcmp (sky, "mode") == 0) {
	mode = True;
	rmean = False;
    } else if (strcmp (sky, "mean") == 0) {
	rmean = True;
	mode = False;
    } else {
        trlerror ("illegal sky value");
        status = INVALID_VALUE;
        return;
    }

    dimx = getNaxis1(ipsci[0]);
    dimy = getNaxis2(ipsci[0]);

    a = (float *) calloc (dimx, sizeof(float));
    b = (short *) calloc (dimx, sizeof(short));
    if (a == NULL || b == NULL) {
        trlerror ("Couldn't allocate memory for sky arrays");
        status = OUT_OF_MEMORY;
        return; 
    }

    if (mode) {

	/* compute MIN and MAX values for data */
	/* use the minimum and twice of the mean to determine the data range */
	data_min = INT_MAX;
	sum = 0.;
	npt = 0;

	initHdr (&dqhdr);
	getHeader(ipdq[0], &dqhdr);

	for (line = 0; line < dimy; line++) {

	     /* read the data in */
	     getFloatLine (ipsci[0], line, a);
	     getShortLine (ipdq[0], line, b);

	     /* Rescale data to counts, if necessary */
	     if (bunit[0] == COUNTRATE) {
		 for (i = 0; i < dimx; ++i) {
		      a[i] *= efac[0];
		 }
	     }

	     for (i = 0; i < dimx; ++i) {
		  if ( (b[i] & badinpdq) == WF3_OK) {
			data_min = (a[i] < data_min) ? a[i] : data_min;
			sum += a[i];
			npt++;
		  }
	     }
	} /* End of loop over lines */

	freeHdr(&dqhdr);

	/* Compute min and max for histogram.
	MIN is min of good data or MINVAL, which ever is greater
	DELTA is difference between mean of data and MIN
	MAX is mean plus DELTA
	This insures that the mean falls in the center of the range
	between min and max. */
	if (npt == 0) npt = 1;
	min = (data_min < MINVAL) ? MINVAL : data_min;
	mean = (sum > 0.) ? (int) ( (sum / (float)npt) + 1) : 1;
	max = 2 * mean - min;
    
	/* use the mode as sky value, use the bin size of 1 (DN) */
	nbins = max - min + 1; 

	/* Insure that there are at least MIN_BINS in the histogram
	and reset the width accordingly. */ 
	if (nbins < MIN_BINS) {
	    nbins = MIN_BINS;
	    hwidth = (float) nbins / (float)MIN_BINS;
	} else if (nbins > MAX_BINS) {
	    hwidth = (float) nbins / (float)MAX_BINS;
	    nbins = MAX_BINS;
	} else {
	    hwidth = 1.;
	}
	hmin = (float) min;

	/*
	sprintf (MsgText, 
	"sky computed using min %d, max %d, mean %g, bins %d, and width %g",
	min, max, mean, nbins, hwidth);
	trlmessage (MsgText);
	*/
    }

    /* Now loop over the input images, computing the sky value for each
    ** image, using either the mode or the resistant mean */
    for (k = 0; k < nimgs; ++k) {

	if (mode) {
	    /*  set up a new histogram array for each image */
	    histgrm = (int *) calloc (nbins, sizeof(int));
	    if (histgrm == NULL){
		    trlerror ("Couldn't allocate memory for sky histogram array");
		    status = OUT_OF_MEMORY;
		return;   
	    }
	} else if (rmean) {
	    skyarr = (float *) calloc (dimx*dimy, sizeof(float));
	    if (skyarr == NULL){
		trlerror ("Couldn't allocate memory for sky array");
		status = OUT_OF_MEMORY;
		return;   
	    }
	    npt = 0;
	}

        initHdr (&dqhdr);
        getHeader (ipdq[k], &dqhdr);
        for (line = 0; line < dimy; line++) {

            /* read the data in */
            getFloatLine (ipsci[k], line, a);
            getShortLine (ipdq[k], line, b);

	    /* Rescale data to counts, if necessary */
	    if (bunit[k] == COUNTRATE) {
		for (i = 0; i < dimx; ++i) {
		     a[i] *= efac[k];
		}
	    }

            /* construct the histogram for the mode calculation */
	    if (mode) {
		for (i = 0; i < dimx; ++i) {
		     if (b[i] == WF3_OK) {

			 /* Adjust the bin position by the width of each bin */
			 if (fabs((a[i]-min)/hwidth) < INT_MAX) {
			     h = (int)((a[i] - min) / hwidth);
			     if (h >= 0 && h < nbins)
				 histgrm[h]++;
			 }
		     }
		}

	    /* load the sky array for calculating the mean */
	    } else if (rmean) {
		for (i = 0; i < dimx; ++i) {
		     if (b[i] == WF3_OK) {
			 skyarr[npt] = a[i];
			 npt++;
		     }
		}
	    }
        } /* End of loop over lines */
        freeHdr(&dqhdr);

        /* calculate the mode from the histogram */
	if (mode) {
            skyval[k] = cr_mode (histgrm, nbins, hwidth, hmin);
            free (histgrm);

	/* calculate the resistant mean */
	} else if (rmean) {
	    resistmean (skyarr, npt, SIGREJ, &skyval[k], &ssig, &smin, &smax);
	    free (skyarr);
	}
    }

    free(a);
    free(b);
}