L2 images ========= L2 images are constructed from :doc:`L1 ` images, which are in turn constructed from idealized :doc:`count ` images. This means that even when constructing L2 images, one must go through the process of simulating how electrons get apportioned among the various reads. It is challenging to realistically model the statistics in the noise of L2 images without going through this process. L2 images are constructed by doing "ramp fitting" on the level 1 images. Each pixel of a level 1 image is a series of "resultants", giving the measured value of that pixel averaged over a series on non-destructive reads as the exposure is being observed. A simple model for a pixel is that its flux as a function of time is simply two numbers: a pedestal and a linear ramp representing the rate at which photons are detected by the pixel. Ramp fitting turns these one-dimensional series of resultants into a "slope" image that is of interest astronomically. Due to details of the H4RG detectors, the pedestals of the ramp vary widely from exposure to exposure, and so current fitting completely throws away as non-astronomical any information in the ramp that is sensitive to the pedestal. The package contains two algorithms for ramp fitting. The first uses "optimal" weighting, considering the full covariance matrix between each of the resultants stemming from read \& Poisson noise from the sources. The covariance is inverted and combined with the design matrix in the usual least-squares approach to solve for the optimal slope and pedestal measurements for each pixel. This approach is naively expensive, but because the covariance matrices for each pixel form a one-dimensional family depending only on the ratio of the flux in the pixel to the read variance, the relevant matrices can be precomputed. The package then then interpolated between these precomputed quantities for each pixel in order to compute the parameters and variances for each pixel. This approach does not handle cosmic rays or saturated pixels well, though for modest sized sets of resultants introducing an additional series of fits for the roughly :math:`2 n_\mathrm{resultant}` sub-ramps would be straightforward. That approach would also naturally handle saturated ramps. Even explicitly computing every possible :math:`n_\mathrm{resultant} (n_\mathrm{resultant} - 1) / 2` subramp would likely still be quite inexpensive for modestly sized ramps. The second approach follows `Casertano (2022) `_. In this approach, a diagonal set of weights is used in place of the full covariance matrix. The choice of weights depend on the particular pattern of reads assigned to each resultant and the amount of flux in the ramp, allowing them to interpolate from simply differencing the first and last resultants when the flux is very large to weighting the resultants by the number of reads when the flux is zero. This approach more efficiently handles dealing with ramps that have been split by cosmic rays, and obtaining uncertainties within a few percent of the "optimal" weighting approach. For these cases, we report final ramp slopes and variances derived from the inverse variance weighted subramp slopes and variances, using the read-noise derived variances. This is a fairly faithful representation of how level two image construction works, so there are not many additional effects to add here. But there are some limitations: * We have a simplistic saturation treatment, and simply clip resultants that exceed the saturation level to the saturation level and throw a flag. L2 source injection =================== We support L2 source injection through :meth:`romanisim.image.inject_sources_into_l2`. This routine is intended for cases when existing L2 images are available, and a small number of sources need to be added on top of those images. The L2 source injection is intended to be a fairly faithful simulation of the process. It includes the following steps: * The model WCS is used to generate the pixel locations for sources. * The number of additional electrons in each pixel is simulated. * A virtual ramp is created that evenly apportions the original L2 flux along the ramp. * The new electrons are apportioned randomly along the ramp following a Poisson distribution in the same way as for the usual L1 simulations. * The new ramp is then fit using the ramp fitting code, and the new fit replaces the old fit in the L2 file. Note that this procedure does not include any new cosmic rays, or any special treatment of pixels that had cosmic rays in them and now have additional source flux. It is hard to do this right since we do not know which pixel the cosmic ray landed in on the basis of the L2 file. If you need more accuracy than this you probably need to directly inject sources into the L1 file. .. automodapi:: romanisim.ramp