def xtalk_pattern(aggressor, frac_scale=0.02): xtalk_frac = {} nside = len(imutils.allAmps()) / 2 for victim in imutils.allAmps(): if (victim != aggressor and (victim - 1) / nside == (aggressor - 1) / nside): dist = abs(victim - aggressor) xtalk_frac[victim] = frac_scale / dist**2 else: xtalk_frac[victim] = 0 return xtalk_frac
def test_rolloff_mask(self): amp_geom = makeAmplifierGeometry(self.input_file) rolloff_mask(self.input_file, self.mask_file, tmp_mask_image=self.image_file, outer_edge_width=self.outer_edge_width, bloom_stop_width=self.bloom_stop_width, signal=self.signal, cleanup=False) image = _FitsFile(self.image_file) mask = _FitsFile(self.mask_file) for amp in imutils.allAmps(self.input_file): # # Unmasked region. # indx = np.where(image[amp] == 0) # # Verify expected sensor perimeter mask along vertical sides. # self.assertEqual(min(indx[0]), amp_geom.imaging.getMinY() + self.outer_edge_width) # # Verify that mask has zero bits set in unmasked region. # self.assertEqual(min(mask[amp][indx].flat), 0) self.assertEqual(max(mask[amp][indx].flat), 0) # # Check that mask area is subset of mask image area. # indx = np.where(mask[amp] != 0) self.assertTrue(min(image[amp][indx].flat) >= self.signal)
def superflat(files, bias_frame=None, outfile='superflat.fits', bitpix=None, bias_subtract=True, bias_method='row'): """ The superflat is created by bias-offset correcting the input files and median-ing them together. """ # Get overscan region. overscan = makeAmplifierGeometry(files[0]).serial_overscan output_images = dict() for amp in imutils.allAmps(files[0]): images = [] for infile in files: image = afwImage.ImageF(infile, imutils.dm_hdu(amp)) if bias_subtract: if bias_frame: bias_image = afwImage.ImageF(bias_frame, imutils.dm_hdu(amp)) image = bias_subtracted_image(image, bias_image, overscan, bias_method) else: image -= imutils.bias_image(im=image, overscan=overscan, bias_method=bias_method) images.append(image) if lsst.afw.__version__.startswith('12.0'): images = afwImage.vectorImageF(images) output_images[amp] = afwMath.statisticsStack(images, afwMath.MEDIAN) imutils.writeFits(output_images, outfile, files[0]) return outfile
def run(self, sensor_id, qe_files, pd_ratio_file, mask_files, gains, bias_frame=None, medians_file=None, vendor_data=False, correction_image=None, mondiode_func=None): imutils.check_temperatures(qe_files, self.config.temp_set_point_tol, setpoint=self.config.temp_set_point, warn_only=True) qe_data = QE.QE_Data(verbose=self.config.verbose, logger=self.log, mondiode_func=mondiode_func) if medians_file is None: medians_file = os.path.join(self.config.output_dir, '%s_QE_medians.txt' % sensor_id) qe_data.calculate_medians(qe_files, medians_file, mask_files=mask_files, bias_frame=bias_frame, overwrite=True, correction_image=correction_image) qe_data.read_medians(medians_file) if vendor_data: qe_data.incidentPower_e2v() else: qe_data.incidentPower(pd_ratio_file) qe_data.calculate_QE(gains, amps=imutils.allAmps(qe_files[0])) fits_outfile = os.path.join(self.config.output_dir, '%s_QE.fits' % sensor_id) qe_data.write_fits_tables(fits_outfile)
def superflat(files, bias_frame=None, outfile='superflat.fits', bitpix=-32, bias_subtract=True): """ The superflat is created by bias-offset correcting the input files and median-ing them together. """ # Get overscan region. overscan = makeAmplifierGeometry(files[0]).serial_overscan # Use the first file as a template for the fits output. output = fits.open(files[0]) for amp in imutils.allAmps(files[0]): images = afwImage.vectorImageF() for infile in files: image = afwImage.ImageF(infile, imutils.dm_hdu(amp)) if bias_subtract: if bias_frame: bias_image = afwImage.ImageF(bias_frame, imutils.dm_hdu(amp)) image = bias_subtracted_image(image, bias_image, overscan) else: image -= imutils.bias_image(image, overscan, statistic=np.median) images.push_back(image) median_image = afwMath.statisticsStack(images, afwMath.MEDIAN) output[amp].data = median_image.getArray() if bitpix is not None: imutils.set_bitpix(output[amp], bitpix) fitsWriteto(output, outfile, clobber=True) return outfile
def fit_gains(self, fitter, gains, gain_errors, sigma_modes, amps=None, hist_nsig=10): "Fit the DN distributions to obtain the system gain per amp." my_gains, my_gain_errors, my_sigma_modes = \ gains, gain_errors, sigma_modes if amps is None: amps = imutils.allAmps() for amp in amps: data = fitter.results(min_prob=self.config.chiprob_min, amp=amp) dn = data['dn'] if len(dn) > 2: try: foo = Fe55GainFitter(dn) kalpha_peak, kalpha_sigma = foo.fit(hist_nsig=hist_nsig) my_gains[amp] = foo.gain my_gain_errors[amp] = foo.gain_error except RuntimeError as eobj: print(eobj) continue try: sigma = sorted( np.concatenate((data['sigmax'], data['sigmay'])) * 10) mode, median, mean = psf_sigma_statistics(sigma, bins=50, range=(2, 6)) my_sigma_modes[amp] = float(mode) except RuntimeError as eobj: print(eobj) continue return my_gains, my_gain_errors, my_sigma_modes
def fitsFile(ccd_segments): headers = fits_headers() output = fits.HDUList() output.append(fits.PrimaryHDU()) output[0].header = headers['PRIMARY'].copy() output[0].header["EXPTIME"] = ccd_segments[0].exptime output[0].header["CCDTEMP"] = ccd_segments[0].ccdtemp for amp, segment in zip(imutils.allAmps(), ccd_segments): output.append(fits.ImageHDU(data=segment.image.getArray())) output[amp].header = headers[headers.keys()[amp]].copy() output[amp].header['BZERO'] = 0 output[amp].name = 'Segment%s' % imutils.channelIds[amp] output[amp].header['DETSIZE'] = segment.geometry[amp]['DETSIZE'] output[amp].header['DATASEC'] = segment.geometry[amp]['DATASEC'] output[amp].header['DETSEC'] = segment.geometry[amp]['DETSEC'] output[amp].header['CHANNEL'] = amp # Add Test Condition and CCD Operating Condition headers with dummy info. output.append(fits.ImageHDU()) for keyword in headers['TEST_COND']: if keyword not in output[-1].header.keys(): output[-1].header.set(keyword, headers['TEST_COND'][keyword]) output.append(fits.ImageHDU()) for keyword in headers['CCD_COND']: if keyword not in output[-1].header.keys(): output[-1].header.set(keyword, headers['CCD_COND'][keyword]) return output
def persist_fe55_gains(): """Persist only the Fe55 gains from the results file.""" raft_id = siteUtils.getUnitId() raft = camera_components.Raft.create_from_etrav(raft_id) results = [] for slot, sensor_id in raft.items(): # Save eotest results file with nominal gains. ccd_vendor = sensor_id.split('-')[0].upper() results_file = '%s_eotest_results.fits' % sensor_id eotestUtils.addHeaderData(results_file, LSST_NUM=sensor_id, TESTTYPE='FE55', DATE=eotestUtils.utc_now_isoformat(), CCD_MANU=ccd_vendor) results.append(lcatr.schema.fileref.make(results_file)) # Persist nominal values to eT results database. amps = imutils.allAmps() gain_data = np.ones(len(amps)) gain_errors = np.zeros(len(amps)) sigmas = np.zeros(len(amps)) for amp, gain_value, gain_error, sigma in zip(amps, gain_data, gain_errors, sigmas): if not np.isfinite(gain_error): gain_error = -1 results.append( lcatr.schema.valid(lcatr.schema.get('fe55_raft_analysis'), amp=amp, gain=gain_value, gain_error=gain_error, psf_sigma=sigma, slot=slot, sensor_id=sensor_id)) return results
def __init__(self, imfile, mask_files=(), bias_frame=None, applyMasks=True, linearity_correction=None): super(MaskedCCD, self).__init__() self.imfile = imfile self.md = imutils.Metadata(imfile) self.amp_geom = makeAmplifierGeometry(imfile) all_amps = imutils.allAmps(imfile) for amp in all_amps: image = afwImage.ImageF(imfile, imutils.dm_hdu(amp)) mask = afwImage_Mask(image.getDimensions()) self[amp] = afwImage.MaskedImageF(image, mask) self._added_mask_types = [] for mask_file in mask_files: self.add_masks(mask_file) self.stat_ctrl = afwMath.StatisticsControl() if mask_files: self.setAllMasks() if bias_frame is not None: self.bias_frame = MaskedCCD(bias_frame) else: self.bias_frame = None self._applyMasks = applyMasks self._linearity_correction = linearity_correction
def writeFits_from_dict(amp_dict, outfile, template_file, bitpix=32): ''' Same as eotest imutils writeFits but takes a dictionary of amplifier as input rather than a list of afwImage images ''' output = fits.HDUList() output.append(fits.PrimaryHDU()) all_amps = imutils.allAmps() for amp in all_amps: if bitpix < 0: output.append(fits.ImageHDU(data=amp_dict[amp])) else: output.append( fits.CompImageHDU(data=amp_dict[amp], compression_type='RICE_1')) with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=UserWarning, append=True) warnings.filterwarnings('ignore', category=AstropyWarning, append=True) warnings.filterwarnings('ignore', category=AstropyUserWarning, append=True) with fits.open(template_file) as template: output[0].header.update(template[0].header) output[0].header['FILENAME'] = outfile for amp in all_amps: output[amp].header.update(template[amp].header) imutils.set_bitpix(output[amp], bitpix) print(np.median(output[amp].data.ravel())) for i in (-3, -2, -1): output.append(template[i]) imutils.fitsWriteto(output, outfile, overwrite=True, checksum=True)
def _read_from_fits(self, infile): all_amps = imutils.allAmps(infile) with fits.open(infile) as foo: hdu = foo['DETECTOR_RESPONSE'] self.flux = np.array(hdu.data.field('FLUX'), dtype=np.float) self.Ne = dict([(amp, np.array(hdu.data.field('AMP%02i_SIGNAL' % amp), dtype=np.float)) for amp in all_amps])
def __init__(self, infile=None): if infile is not None: print "Using %s for the crosstalk pattern" % infile xtalk_matrix = CrosstalkMatrix(infile) self.matrix = xtalk_matrix.matrix else: # Use default matrix. pattern = (0.01, 0.02, 1, 0.02, 0.01) offsets = (-2, -1, 0, 1, 2) namps = len(imutils.allAmps()) self.matrix = np.zeros((namps, namps), dtype=np.float) for agg in imutils.allAmps(): for offset, value in zip(offsets, pattern): vic = agg + offset if (vic in range(1, 9) and agg in range(1, 9) or vic in range(9, 17) and agg in range(9, 17)): self.matrix[agg - 1][vic - 1] = value
def __init__(self, infile): amp_geom = makeAmplifierGeometry(infile) xmin, xmax = amp_geom.imaging.getMinX(), amp_geom.imaging.getMaxX() super(_FitsFile, self).__init__() with fits.open(infile) as foo: amps = imutils.allAmps(infile) for amp in amps: self[amp] = copy.deepcopy(foo[amp].data[:, xmin:xmax])
def read_medians(self, medians_file): data = np.recfromtxt(medians_file) data = data.transpose() self.wl = data[0] self.exptime = data[1] self.pd = data[2] self.medians = dict([(amp, col) for amp, col in zip(imutils.allAmps(), data[3:])])
def numGoodFits(self, chiprob_min=0.1): chiprob = np.array(self.chiprob) amps = np.sort(np.unique(np.array(self.amp))) my_numGoodFits = dict([(amp, 0) for amp in imutils.allAmps()]) for amp in amps: indx = np.where((self.chiprob > chiprob_min) & (self.amp == amp)) my_numGoodFits[amp] = len(indx[0]) return my_numGoodFits
def run(self, sensor_id, infiles, mask_files, gains, detrespfile=None, bias_frame=None, max_pd_frac_dev=0.05, linearity_spec_range=(1e3, 9e4), use_exptime=False): self.sensor_id = sensor_id self.infiles = infiles self.mask_files = mask_files self.gains = gains self.bias_frame = bias_frame self.max_pd_frac_dev = max_pd_frac_dev if detrespfile is None: # # Compute detector response from flat pair files. # detrespfile = self.extract_det_response(use_exptime) # # Perform full well and linearity analyses. # detresp = DetectorResponse(detrespfile) outfile = self.config.eotest_results_file if outfile is None: outfile = os.path.join(self.config.output_dir, '%s_eotest_results.fits' % self.sensor_id) all_amps = imutils.allAmps(detrespfile) output = EOTestResults(outfile, namps=len(all_amps)) if self.config.verbose: self.log.info("Amp full well (e-/pixel) max. frac. dev.") for amp in all_amps: try: full_well, fp = detresp.full_well(amp) except StandardError as eobj: self.log.info("Exception caught in full well calculation:") self.log.info(str(eobj)) full_well = None self.log.info('linearity analysis range: %s, %s' % linearity_spec_range) try: maxdev, fit_pars, Ne, flux = \ detresp.linearity(amp, spec_range=linearity_spec_range) except StandardError as eobj: self.log.info("Exception caught in linearity calculation:") self.log.info(str(eobj)) maxdev = None if self.config.verbose: self.log.info('%2i %s %s' % (amp, full_well, maxdev)) if full_well is not None: output.add_seg_result(amp, 'FULL_WELL', full_well) if maxdev is not None: output.add_seg_result(amp, 'MAX_FRAC_DEV', float(maxdev)) output.write()
def run(self, sensor_id, dark_files, mask_files, gains, bias_frame=None): imutils.check_temperatures(dark_files, self.config.temp_set_point_tol, setpoint=self.config.temp_set_point, warn_only=True) median_images = {} for amp in imutils.allAmps(dark_files[0]): median_images[amp] = imutils.fits_median(dark_files, imutils.dm_hdu(amp)) medfile = os.path.join(self.config.output_dir, '%s_median_dark_bp.fits' % sensor_id) imutils.writeFits(median_images, medfile, dark_files[0]) ccd = MaskedCCD(medfile, mask_files=mask_files, bias_frame=bias_frame) md = imutils.Metadata(dark_files[0], 1) exptime = ccd.md.get('EXPTIME') total_bright_pixels = 0 total_bright_columns = 0 if self.config.verbose: self.log.info("Amp # bright pixels # bright columns") # # Write bright pixel and column counts to results file. # 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)) pixels = {} columns = {} for amp in ccd: bright_pixels = BrightPixels(ccd, amp, exptime, gains[amp]) pixels[amp], columns[amp] = bright_pixels.find() pix_count = len(pixels[amp]) col_count = len(columns[amp]) total_bright_pixels += pix_count total_bright_columns += col_count results.add_seg_result(amp, 'NUM_BRIGHT_PIXELS', pix_count) results.add_seg_result(amp, 'NUM_BRIGHT_COLUMNS', col_count) self.log.info("%2i %i %i" % (amp, pix_count, col_count)) if self.config.verbose: self.log.info("Total bright pixels: %i" % total_bright_pixels) self.log.info("Total bright columns: %i" % total_bright_columns) results.write(clobber=True) # Generate the mask file based on the pixel and columns. mask_file = os.path.join(self.config.output_dir, '%s_bright_pixel_mask.fits' % sensor_id) if os.path.isfile(mask_file): os.remove(mask_file) generate_mask(medfile, mask_file, self.config.mask_plane, pixels=pixels, columns=columns)
def system_gains(self): if self.args.db_credentials is not None: return SensorGains(vendor=self.args.Vendor, vendorId=self.args.sensor_id, db_credentials=self.args.db_credentials) else: results = EOTestResults(self.args.gains) gains = results['GAIN'] return dict([(amp, gains[amp - 1]) for amp in imutils.allAmps()])
def run(self, sensor_id, infiles, mask_files, gains, binsize=1, bias_frame=None): outfile = os.path.join(self.config.output_dir, '%s_ptc.fits' % sensor_id) all_amps = imutils.allAmps(infiles[0]) ptc_stats = dict([(amp, ([], [])) for amp in all_amps]) exposure = [] file1s = sorted([item for item in infiles if item.find('flat1') != -1]) for flat1 in file1s: flat2 = find_flat2(flat1) if self.config.verbose: self.log.info("processing %s" % flat1) exposure.append(exptime(flat1)) ccd1 = MaskedCCD(flat1, mask_files=mask_files, bias_frame=bias_frame) ccd2 = MaskedCCD(flat2, mask_files=mask_files, bias_frame=bias_frame) for amp in ccd1: results = flat_pair_stats(ccd1, ccd2, amp, mask_files=mask_files, bias_frame=bias_frame) ptc_stats[amp][0].append(results.flat_mean) ptc_stats[amp][1].append(results.flat_var) self._fit_curves(ptc_stats, sensor_id) output = fits.HDUList() output.append(fits.PrimaryHDU()) colnames = ['EXPOSURE'] units = ['seconds'] columns = [np.array(exposure, dtype=np.float)] for amp in all_amps: colnames.extend(['AMP%02i_MEAN' % amp, 'AMP%02i_VAR' % amp]) units.extend(['ADU', 'ADU**2']) columns.extend([ np.array(ptc_stats[amp][0], dtype=np.float), np.array(ptc_stats[amp][1], dtype=np.float) ]) formats = 'E' * len(colnames) fits_cols = [ fits.Column(name=colnames[i], format=formats[i], unit=units[i], array=columns[i]) for i in range(len(columns)) ] output.append(fitsTableFactory(fits_cols)) output[-1].name = 'PTC_STATS' output[0].header['NAMPS'] = len(all_amps) fitsWriteto(output, outfile, clobber=True)
def sensor_CTI(flatname, verbose): result = [] amps = imutils.allAmps(flatname) s_task = EPERTask() s_task.config.direction = 's' s_task.config.verbose = verbose s_task.config.cti = True scti, bias_ests = s_task.run(flatname, 2, amps, 2) return scti
def noise_dists(imfile, gains, sampler, mask_files=()): if imfile is None: return dict([(amp, np.zeros(len(sampler.xarr), dtype=np.float)) for amp in imutils.allAmps()]) ccd = MaskedCCD(imfile, mask_files=mask_files) my_noise_dists = NoiseDistributions(amps=ccd.keys()) for amp in ccd: my_noise_dists[amp] = noise_samples(ccd[amp], gains[amp], sampler, ccd.stat_ctrl) return my_noise_dists
def get_overscans(infile, oscan_indices=None): "Return the overscan data as numpy arrays." if oscan_indices is None: y0, y1, x0, x1 = get_oscan_indices(infile) else: y0, y1, x0, x1 = oscan_indices overscans = dict() for amp in imutils.allAmps(infile): oscan_data = afw_image.ImageF(infile, imutils.dm_hdu(amp)).getArray() overscans[amp] = copy.deepcopy(oscan_data[y0:y1, x0:x1]) return overscans
def _compute_gain_selection(self, ptc, gain_range, infile): self._index = {} if ptc is None or gain_range is None: return if len(ptc[1].data.field('AMP01_MEAN')) != len(self.flux): raise RuntimeError('Number of measurements in PTC file ' + 'differs from detector response file.') for amp in imutils.allAmps(infile): mean = ptc[1].data.field('AMP%02i_MEAN' % amp) var = ptc[1].data.field('AMP%02i_VAR' % amp) gain = mean/var self._index[amp] = np.where((gain >= gain_range[0]) & (gain <= gain_range[1]))
def multiaggressor_amplifier_coords(nx, ny, xpos=_xpos, ypos=_ypos): """ Return dictionaries (keyed by amplifier) of x, y pixel locations of aggressor images translated from detector coordinates to amplifier coordinates. """ amp_coords = AmpCoords(nx, ny) x, y = {}, {} for amp, xx, yy in zip(imutils.allAmps(), xpos, ypos): my_amp, x[amp], y[amp] = amp_coords(xx, yy) if amp != my_amp: raise RuntimeError("multiaggressor amp mismatch") return x, y
def generate_superflat(pars): print "Generating superflat dataset..." superflat = pars.superflat outputdir, sensor_id = setup(pars, superflat.test_type) tempfile = os.path.join(outputdir, 'superflat_temp.fits') dark_cols = None dark_pix = None # # Set incident flux (ph/s/pixel) so that full well is attained in # a single exposure (but also disable full well below). # intensity = pars.full_well * pars.system_gain / superflat.exptime for frame in range(superflat.nframes): print " frame", frame sensor = simulate_frame(superflat.exptime, pars, set_full_well=False) sensor.expose_flat(intensity) # Generate dark column and dark pixel locations only once and # apply the same sets of locations to each frame. if dark_cols is None: dark_cols = sensor.generate_bright_cols(superflat.dark_ncols) if dark_pix is None: dark_pix = sensor.generate_bright_pix(superflat.dark_npix) sensor.set_dark_cols(dark_cols, superflat.dark_frac) sensor.set_dark_pix(dark_pix, superflat.dark_frac) sensor.md['MONOWL'] = superflat.wavelength sensor.md['TESTTYPE'] = 'SFLAT_500' sensor.md['IMGTYPE'] = 'FLAT' sensor.md['LSST_NUM'] = sensor_id sensor.md['PCTI'] = superflat.pcti sensor.md['SCTI'] = superflat.scti sensor.writeto(tempfile) foo = ctesim(tempfile, pcti=superflat.pcti, scti=superflat.scti, verbose=superflat.verbose) filename = ("%s_%s_flat_%02i_%s.fits" % (sensor_id, superflat.test_type, frame, time_stamp(debug=pars.debug))) foo.writeto(os.path.join(outputdir, filename), clobber=True) # # Generate non-uniform illumination correction file. For these # simulations, we set every pixel to unity, i.e., no correction. # print " generating the non-uniform illumination correction file..." sensor = ccd(exptime=0) for amp in imutils.allAmps(): sensor.segments[amp].image += 1 filename = ("%s_illumation_correction_%s.fits" % (sensor_id, time_stamp(debug=pars.debug))) sensor.writeto(os.path.join(outputdir, filename), bitpix=pars.bitpix)
def setUp(self): self.matrix_text_output = 'xtalk_output.txt' self.matrix_fits_output = 'xtalk_output.fits' self.xtalk_files = [] for agg in imutils.allAmps(): self.xtalk_files.append('xtalk_test_%02i.fits' % agg) xtalk_frac = sim_tools.xtalk_pattern(agg) ccd = generate_crosstalk_frame(agg, 2000, 250, 250, 20, xtalk_frac=xtalk_frac) ccd.writeto(self.xtalk_files[-1])
def generate_crosstalk_dataset(pars): print "Generating spot dataset..." spot = pars.spot outputdir, sensor_id = setup(pars, spot.test_type) if spot.multiaggressor: sensors = AmpIndexDecorator( dark_frame(spot.exptime, spot.ccdtemp, pars)) else: sensors = dict((amp, dark_frame(spot.exptime, spot.ccdtemp, pars)) for amp in imutils.allAmps()) for aggressor in imutils.allAmps(): print " aggressor amp", aggressor xtalk_frac = spot.xtalk_pattern(aggressor, spot.frac_scale) sensor = sensors[aggressor] xx, yy, radius = (AmpIndexDecorator(item)[aggressor] for item in (spot.x, spot.y, spot.radius)) for amp in sensor.segments: if amp == aggressor: sensor.segments[amp].add_spot_image(spot.dn, xx, yy, radius) else: dn = spot.dn * xtalk_frac[amp] sensor.segments[amp].add_spot_image(dn, xx, yy, radius) # sensor.md['TESTTYPE'] = 'SPOT' sensor.md['IMGTYPE'] = 'SPOT' sensor.md['LSST_NUM'] = sensor_id if spot.multiaggressor: filename = ("%s_%s_spot_multi_%s.fits" % (sensor_id, spot.test_type, time_stamp(debug=pars.debug))) sensor.writeto(os.path.join(outputdir, filename), bitpix=pars.bitpix) else: for aggressor in imutils.allAmps(): filename = ("%s_%s_spot_%02i_%s.fits" % (sensor_id, spot.test_type, aggressor, time_stamp(debug=pars.debug))) sensors[aggressor].writeto(os.path.join(outputdir, filename), bitpix=pars.bitpix)
def check_noao_keywords(infile, verbose=True): defects = [] input = fits.open(infile) def geom_kwd(x): return parse_geom_kwd(input[0].header[x]) # Sanity check for DETSIZE in PHDU try: pdetsize = geom_kwd('DETSIZE') if (pdetsize['xmin'] != 1 or pdetsize['ymin'] != 1 or pdetsize['xmax'] <= pdetsize['xmin'] or pdetsize['ymax'] <= pdetsize['ymin']): defects.append("Primary HDU DETSIZE fails sanity check: %s" % input[0].header['DETSIZE']) except KeyError: pdetsize = None defects.append("Primary HDU: missing DETSIZE keyword") for extnum in imutils.allAmps(infile): def geom_kwd(x): return parse_geom_kwd(input[extnum].header[x]) try: detsec = geom_kwd('DETSEC') except KeyError: detsec = None defects.append("HDU %i: missing DETSEC keyword" % extnum) try: datasec = geom_kwd('DATASEC') except KeyError: datasec = None defects.append("HDU %i: missing DATASEC keyword" % extnum) if datasec is not None and datasec['xmin'] <= 1: defects.append("HDU %i, No prescan pixels implied by DATASEC: %s" % (extnum, input[extnum].header['DATASEC'])) if (datasec is not None and detsec is not None and (abs(datasec['xmin'] - datasec['xmax']) != abs(detsec['xmin'] - detsec['xmax']) or abs(datasec['ymin'] - datasec['ymax']) != abs(detsec['ymin'] - detsec['ymax']))): defects.append( "HDU %i, inconsistent DETSEC and DATASEC sizes: %s %s" % (extnum, input[extnum].header['DETSEC'], input[extnum].header['DATASEC'])) if verbose and defects: for item in defects: print(item) return defects
def get_mean_overscans(infiles, oscan_indices=None): "Compute the mean of the overscans of the list of files" if oscan_indices is None: y0, y1, x0, x1 = get_oscan_indices(infiles[0]) else: y0, y1, x0, x1 = oscan_indices mean_overscans = defaultdict(list) for infile in infiles: for amp in imutils.allAmps(infiles[0]): oscan_data \ = afw_image.ImageF(infile, imutils.dm_hdu(amp)).getArray() mean_overscans[amp].append(copy.deepcopy(oscan_data[y0:y1, x0:x1])) for amp, images in mean_overscans.items(): mean_overscans[amp] = sum(images) / float(len(images)) return mean_overscans
def read_fe55_catalog(self, psf_catalog, chiprob_min=0.1): catalog = fits.open(psf_catalog) for attr in 'sigmax sigmay dn dn_fp_sum chiprob amp'.split(): exec('self.%s = np.array((), dtype=float)' % attr) for amp in imutils.allAmps(psf_catalog): extname = 'Amp%02i' % amp chiprob = catalog[extname].data.field('CHIPROB') index = np.where(chiprob > chiprob_min) self.chiprob = np.concatenate((self.chiprob, chiprob[index])) self.amp = np.concatenate((self.amp, np.ones(len(index[0])) * amp)) for attr in 'sigmax sigmay dn dn_fp_sum'.split(): command = 'self.%(attr)s = np.concatenate((self.%(attr)s, catalog["%(extname)s"].data.field("%(attr)s")[index]))' % locals( ) exec(command) self.dn_fp = self.dn_fp_sum