Example #1
0
def _write_read_noise_dists(outfile, Ntot, Nsys, gains, bias, sysnoise):
    output = fits.HDUList()
    output.append(fits.PrimaryHDU())
    output[0].header['BIASFILE'] = bias
    output[0].header['SYSNFILE'] = str(sysnoise)
    for amp in Ntot:
        sigtot, sigsys = Ntot[amp], Nsys[amp]
        nread_col = fits.Column(name="TOTAL_NOISE",
                                format="E",
                                unit="e- rms",
                                array=sigtot)
        nsys_col = fits.Column(name="SYSTEM_NOISE",
                               format="E",
                               unit="e- rms",
                               array=sigsys)
        output.append(fitsTableFactory((nread_col, nsys_col)))
        output[amp].name = "SEGMENT%s" % imutils.channelIds[amp]
        output[0].header["GAIN%s" % imutils.channelIds[amp]] = gains[amp]
        output[0].header["SIGTOT%s" % imutils.channelIds[amp]] = \
            imutils.median(sigtot)
        output[0].header["SIGSYS%s" % imutils.channelIds[amp]] = \
            imutils.median(sigsys)
    fitsWriteto(output, outfile, clobber=True)
Example #2
0
def ctesim(infile, pcti=0, scti=0, verbose=False):
    input = fits.open(infile)
    amps = [
        i for i in range(1, len(input))
        if input[i].name.upper().startswith('SEGMENT')
    ]
    if not isinstance(pcti, dict):
        pcti = {amp: pcti for amp in amps}
    if not isinstance(scti, dict):
        scti = {amp: scti for amp in amps}
    segments = {}
    for amp in amps:
        if verbose:
            print("ctesim: working on amp", amp)
        image = afwImage.ImageF(infile, imutils.dm_hdu(amp))
        geom = makeAmplifierGeometry(infile)
        #
        # Temporarily remove readout bias median.
        #
        bias_med = imutils.median(image.Factory(image, geom.serial_overscan))

        image -= bias_med

        imarr = image.getArray()

        outimage = afwImage.ImageF(image, True)
        outarr = outimage.getArray()
        if pcti[amp] != 0:
            pcte_matrix = cte_matrix(imarr.shape[0], pcti[amp])
            for col in range(0, imarr.shape[1]):
                outarr[:, col] = np.dot(pcte_matrix, imarr[:, col])
        if scti[amp] != 0:
            scte_matrix = cte_matrix(imarr.shape[1], scti[amp])
            for row in range(0, imarr.shape[0]):
                outarr[row, :] = np.dot(scte_matrix, outarr[row, :])
        #
        # Restore readout bias
        #
        outarr += bias_med
        segments[amp] = outimage

    return fitsFile(segments, input)
Example #3
0
    def run(self,
            sensor_id,
            bias_files,
            gains,
            system_noise_files=None,
            system_noise=None,
            mask_files=(),
            use_overscan=False):
        all_amps = imutils.allAmps(bias_files[0])
        imutils.check_temperatures(bias_files,
                                   self.config.temp_set_point_tol,
                                   setpoint=self.config.temp_set_point,
                                   warn_only=True)
        outfiles = []
        Ntot = NoiseDistributions(amps=all_amps)
        Nsys = NoiseDistributions(amps=all_amps)
        if system_noise_files is None:
            system_noise_files = [None] * len(bias_files)
        for i, bias, sysnoise in zip(range(len(bias_files)), bias_files,
                                     system_noise_files):
            outfile = "%s_read_noise_%03i.fits" % (sensor_id, i)
            outfile = os.path.join(self.config.output_dir, outfile)
            outfiles.append(outfile)

            if self.config.verbose:
                self.log.info("Processing %s %s -> %s" %
                              (bias, sysnoise, outfile))

            # Determine the nominal imaging region from the bias file.
            ccd = MaskedCCD(bias)
            if use_overscan:
                imaging = ccd.amp_geom.serial_overscan
                dx = imaging.getWidth() / 2
                dy = self.config.dy
                nsamp = self.config.nsamp
            else:
                imaging = ccd.amp_geom.imaging
                dx = self.config.dx
                dy = self.config.dy
                nsamp = self.config.nsamp
            #
            # Create a single sub-region sampler so that the same
            # sub-regions will be used for both the bias and system
            # noise frames.
            #
            sampler = imutils.SubRegionSampler(dx, dy, nsamp, imaging=imaging)

            Ntot_amp = noise_dists(bias, gains, sampler, mask_files=mask_files)
            Nsys_amp = noise_dists(sysnoise,
                                   gains,
                                   sampler,
                                   mask_files=mask_files)

            _write_read_noise_dists(outfile, Ntot_amp, Nsys_amp, gains, bias,
                                    sysnoise)
            #
            # Accumulate noise distributions for final median calculation
            #
            Ntot.append(Ntot_amp)
            Nsys.append(Nsys_amp)

        results_file = self.config.eotest_results_file
        if results_file is None:
            results_file = os.path.join(self.config.output_dir,
                                        '%s_eotest_results.fits' % sensor_id)

        results = EOTestResults(results_file, namps=len(ccd))
        if self.config.verbose:
            self.log.info("Amp    read noise    total noise    system noise")
        for amp in ccd:
            Ntot_med = imutils.median(Ntot[amp])
            if system_noise is not None:
                Nsys_med = float(system_noise[amp])
            else:
                Nsys_med = imutils.median(Nsys[amp])
            var = Ntot_med**2 - Nsys_med**2
            if var >= 0:
                Nread = np.sqrt(var)
            else:
                Nread = -1
            line = "%2s       %7.4f        %7.4f        %7.4f" % (
                amp, Nread, Ntot_med, Nsys_med)
            if self.config.verbose:
                self.log.info(line)
            results.add_seg_result(amp, 'READ_NOISE', Nread)
            results.add_seg_result(amp, 'TOTAL_NOISE', Ntot_med)
            results.add_seg_result(amp, 'SYSTEM_NOISE', Nsys_med)
        results.write(clobber=True)
Example #4
0
        seg.add_bias(sigma=4)  # CCD read noise
        bias_segs.append(seg)
    writeFits(bias_segs, bias_file)
    #
    # Simulate readout system noise.
    #
    readout_noise_file = 'readout_noise.fits'
    noise_segs = []
    for amp in gains:
        seg = SegmentExposure(exptime=0, gain=gains[amp])
        seg.add_bias(level=1e4, sigma=5)  # electronic bias and noise
        noise_segs.append(seg)
    writeFits(noise_segs, readout_noise_file)
    #
    # Compute the distribution of noise estimates.
    #
    dx, dy = 100, 100
    nsamp = 1000
    imaging = imutils.imaging
    sampler = imutils.SubRegionSampler(dx, dy, nsamp, imaging)
    #mask_files = ('CCD250_DEFECTS_mask.fits',)
    mask_files = ()
    Ntot = noise_dists(bias_file, gains, sampler, mask_files=mask_files)
    Nsys = noise_dists(readout_noise_file, gains, sampler, mask_files)
    #
    # Read noise distribution.
    #
    for amp in Ntot:
        Nread = np.sqrt(Ntot[amp] * Ntot[amp] - Nsys[amp] * Nsys[amp])
        print imutils.median(Nread), imutils.stdev(Nread)