Stack Analysis (ppStack)

Stack Masks

Updates added 2010.10.29 : Previously, we were only setting bad mask bits, and only setting a single vale (BLANK) for all bits. As of ipp-20101029, the code now does the following:

  • for bad pixels, set the output mask to the OR of all bad input pixels
  • for good pixels (ie, a value is calculated), set the output mask to the fuzzy AND of the inputs pixels actually used to calculate the output pixel value. The fuzzy AND raises a bit if 65% of the input pixels see that bit. This change was necessary to allow the nightly stacks to include information about suspect pixels due to, eg, excessive burntool or excessive diffraction spikes. The suspect nature of the pixel folds into the PSF_QF_PERFECT score (psf-weighted fraction of pixels with neither BAD nor SUSPECT pixels).

Stack Zero Points

UPDATE 2012.11.28 : the discussion below is correct, but one wrinkle is that the airmass slopes (c1 in the equations below, ZP.AIRMASS in ppStack.config) have been left at 0.0. Thus, the airmass extinctions for the different input images have not been corrected based on the airmass of the images. Instead, the zero points have been tweaked by the relative photometry analysis in the assumption of some possible cloud levels. Thus, the output stack effectively has a zero point of 25.0 (the value for ZP.TARGET) and an airmass of 0.0. Also note that the photometry from the stack is re-calibrated relative to the reference catalog (currently, an ubercal-based reference). However, this calibration process also ignores the airmass (because it was originally written for the synthetic photometry database with poor photometry quality). Thus, the re-calibration tends to find zero points which are close to 25.0. In future (after the current, 2012.07.06, version of the LAP re-analysis is done), we need to set the correct airmass slope terms in ppStack.config and also include it in the zero point calibration.

Here is a description of how the stack zero points are determined and set:

  • in ppStackInputPhotometer
    • if (ppStack:PHOT), remeasure photometry of the sources used by ppStack [do we trust pswarp photometry or not?]
  • in ppStackSources:
    • extract the reported zero points for each exposure
      • if all are valid (not NAN), use these as the zero points
      • otherwise use the recipe values (25.0 at the time of this writing)
        • this explains some jumps: if any image was missing the zero point, the stack would end up with a reference zero point of essentially 25.0 -- from the ppStack recipe file -- otherwise it would be essentially the zero point of the given filter (relative to grizy.synth).
    • if (ppStack:MATCH.ZERO.POINTS), use relative photometry to set the zero point:
      • pmSourceMatchRelphot returns the set of transparencies that minimize the chisq [the 'photometric clump' is set to 0.0 offset]
      • transparency is defined as: M_app = m_inst + zp + c1 * airmass + 2.5log(t) - transparency
      • the transparencies are applied to the reported zero points
    • the zero points are adjusted by the exptime and airmass of the image to determine the magnitude offset needed to place the image in the desired flux scale. note the following long comment from ppStackSource.c explaining the modification
      	// For any star, the observed instrumental magnitude on an image and the apparent magnitude are related by:
      	// M_app = m_inst + zp + c1 * airmass + 2.5log(t) - transparency
      	// NOTE the sign of 'transparency'  this must agree with the definition in pmSourceMatch.c. see, eg, line 457 where 
      	// transparency = m_inst + zp + c1 * airmass + 2.5log(t) - M_app 
      	// we want to adjust the input images to be in a consistent flux system so that the
      	// final stack can be generated with a specific target zero point.  Any adjustment to
      	// the flux scale of the image must be made in coordination with the resulting
      	// zeropoint, exposure time, and airmass such that the above relationship yields the
      	// same apparent magnitude for a given star:
      	// m_inst_i : instrumental mags on input image (in)
      	// m_inst_o : instrumental mags on re-normalized image (out)
      	// m_inst_o + zp_o + c1 * airmass_o + 2.5log(t_o) - trans_o = m_inst_i + zp_i + c1 * airmass_i + 2.5log(t_i) - trans_i
      	// m_inst_o = m_inst_i + (zp_i - zp_o) + c1 * (airmass_i - airmass_o) + 2.5log(t_i) - 2.5log(t_o) - trans_i + trans_o
      	// zp_i, airmass_i, t_i, trans_i : reported or measured for input image
      	// zp_o      = zpTarget      (from recipe)
      	// airmass_o = airmassTarget (from recipe)
      	// t_o       = sumExpTime    [sum of input exposure times: once images are scale to this time, they can be avereaged]
      	// trans_o   = 0.0           [obviously!]
      	// we have 2 cases: (a) all reported ZPs are good or (b) some are bad:
      	// (a) FPA.ZP = zp_i + c1 * airmass_i
      	//  --> zp[i] = zp_i + c1 * airmass_i + 2.5log(exptime_i)
      	// (b)  zp[i] = c1 * airmass_i + 2.5log(exptime_i)
      	// NOTE: in case (b), the current code is equating the TARGET zp with the NOMINAL zp, which is wrong.
      	// m_inst_o - m_inst_i = zp[i] - zpTarget - c1 * airmassTarget - 2.5log(sumExpTime) - trans_i
    • It also seems that the ouput reported ZP of a stack for which any input ZPs are NAN is also NAN by construction (ppStackSources.c:344), but the pixels will have flux values based on the assumed input zero points of 25.0.
    • at this point, we have a vector ‘options->norm’ with the mag offset values.
    • in ppStackSources, the vector of norms above are used to adjust the magnitudes of the sources used to generate the fake sources in the convolution target image. After the convolution is done, the convolved image is then corrected by the ratio of the relphot-based correction and the kernel-based correction (which should be close to 1.0). This puts the image back into the flux scale expected for the relphot-based measurement.
  • in ppStackConvolve, the metadata for each input image (FPA.ZP, FPA.EXPOSURE, CELL.EXPOSURE, CELL.SATURATION) are adjusted to match the renormalization.