def __init__(self, filename, distance): fits = pyfits.open(filename) # compress all images into one image by average all the pixels if len(fits[0].data.shape) == 3: print("Found {0} exposures. Averaging...".format( fits[0].data.shape[0])) data = np.average(fits[0].data, axis=0) else: data = fits[0].data # create the wcs information w = WCS(naxis=2) w.wcs.crpix = [0, 0] plate_scale = foxsi_optics_calib.plate_scale(distance).to('arcsec') w.wcs.cdelt = plate_scale.value * np.ones(2) w.wcs.crval = [0, 0] w.wcs.ctype = ["TAN", "TAN"] CCDData.__init__(self, data, wcs=w, unit='adu', header=deepcopy(fits[0].header)) # save the name of the filename self.filename = os.path.basename(filename) x, y = np.meshgrid(*[np.arange(v) for v in self.data.shape]) * u.pixel self.xaxis, self.yaxis = self.wcs.wcs_pix2world(x, y, 1) * u.arcsec self.xlim = np.floor( [np.min(self.xaxis).value, np.max(self.xaxis).value]) self.ylim = np.floor( [np.min(self.yaxis).value, np.max(self.yaxis).value])
def __init__(self, filename, pinhole_size=0.05 * u.mm): xy = [] spectra = [] self.energy_axis = (ENERGY_CALIB_M * (np.arange(0, NUMBER_OF_CHANNELS) + 1) - ENERGY_CALIB_B) * u.keV self.filename = filename self.position, self.data = self._parse_file(filename) self.pinhole_size = pinhole_size self.plate_scale = foxsi_optics_calib.plate_scale(1 * u.mm) self.error = np.sqrt(self.data.value) * u.count # recenter based on max position total_counts = np.sum(self.data, axis=1) max_position = self.position[np.argmax(total_counts), 1] self.position[:, 1] = self.position[:, 1] - max_position self._fit()
def plot_scan(self, energy_range=None, ax=None): if not ax: ax = plt.subplot() total_counts = np.sum(self.data, axis=1) err_counts = np.sqrt(total_counts.value) * u.count norm_rate = total_counts / (self.exposure_time * total_counts.max()) norm_rate_error = err_counts / (self.exposure_time * total_counts.max()) x = self.position[:, 1] x_arcsec = x * self.plate_scale xerr = foxsi_optics_calib.plate_scale(self.pinhole_size) ax.errorbar(x_arcsec.value, norm_rate.value, yerr=norm_rate_error.value, xerr=xerr.value) ax.set_ylabel('Normalized Rate') ax.set_xlabel('Position [arcsec]') ax.set_yscale('log')
def __init__(self, im, offaxis_angle, polar_angle, shift=False): self.im = im # define the wcs system self.w = WCS(naxis=2) self.w.wcs.crpix = np.unravel_index(np.argmax(self.im), self.im.shape) self.w.wcs.cdelt = foxsi_optics_calib.plate_scale(foxsi_optics_calib.CCD_PIXEL_PITCH).value * np.ones(2) self.w.wcs.crval = [0, 0] self.w.wcs.ctype = ["TAN", "TAN"] self.plate_scale = self.w.wcs.cdelt * u.arcsec self.polar_angle = polar_angle self.offaxis_angle = offaxis_angle pitch, yaw = (-np.sin(self.polar_angle) * self.offaxis_angle, np.cos(self.polar_angle) * self.offaxis_angle) self.pitch = pitch self.yaw = yaw # offset is pitch then yaw self.offset = u.Quantity([pitch, yaw]) if shift: self.w.wcs.crval += [self.yaw.to('arcsec').value, self.pitch.to('arcsec').value] x, y = np.meshgrid(*[np.arange(v) for v in self.im.shape]) * u.pixel self.xaxis, self.yaxis = self.w.wcs_pix2world(x, y, 1) * u.arcsec
from astropy.wcs import WCS import astropy.units as u import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LogNorm import scipy.optimize as opt from astropy.modeling.fitting import LevMarLSQFitter from astropy.io import fits as pyfits from astropy.nddata import CCDData from copy import deepcopy import os.path import foxsi_optics_calib from foxsi_optics_calib.psf import psf2d, psf_x, psf_y, calculate_best_guess_params, PSF2DModel CCD_PLATE_SCALE = foxsi_optics_calib.plate_scale(foxsi_optics_calib.CCD_PIXEL_PITCH).value class AndorCCDImage(CCDData): """ A generic class to handle fits files created by the Andor CCD. This is a general class to inspect a file and makes no assumptions about the image. This class inherits from `~astropy.nddata.CCDData`. Parameters ---------- data : `~numpy.ndarray` A 2d ndarray containing the image meta : dict-like object or None, optional Metadata for this object.