def to_model(data, meta): """ Create a photutils GriddedPSFModel object from input data and meta information Parameters ---------- data : ndarray 3D numpy array of PSFs at different points across the detector meta : dict Dictionary containing meta data Returns ------- model : GriddedPSFModel Photutils object with 3D data array and metadata with specified grid_xypos and oversampling keys """ try: from photutils import GriddedPSFModel except ImportError: raise ImportError("This method requires photutils >= 0.6") ndd = NDData(data, meta=meta, copy=True) ndd.meta['grid_xypos'] = [((float(ndd.meta[key][0].split(',')[1].split(')')[0])), (float(ndd.meta[key][0].split(',')[0].split('(')[1]))) for key in ndd.meta.keys() if "DET_YX" in key] ndd.meta['oversampling'] = meta["OVERSAMP"][0] # just pull the value ndd.meta = {key.lower(): ndd.meta[key] for key in ndd.meta} model = GriddedPSFModel(ndd) return model
def to_griddedpsfmodel(HDUlist_or_filename=None, ext=0): """ Create a photutils GriddedPSFModel object from either a FITS file or an HDUlist object. The input must have header keywords "DET_YX{}" and "OVERSAMP" (will be present if psf_grid() is used to create the file). Parameters ---------- HDUlist_or_filename : string Either a fits.HDUList object or a filename of a FITS file on disk ext : int Extension in that FITS file Returns ------- model : GriddedPSFModel Photutils object with 3D data array and metadata with specified grid_xypos and oversampling keys """ try: from photutils import GriddedPSFModel except ImportError: raise ImportError("This method requires photutils >= 0.6") if isinstance(HDUlist_or_filename, str): HDUlist = fits.open(HDUlist_or_filename) elif isinstance(HDUlist_or_filename, fits.HDUList): HDUlist = HDUlist_or_filename else: raise ValueError('Input must be a filename or HDUlist') data = HDUlist[ext].data header = HDUlist[ext].header # Check necessary keys are there if not any("DET_YX" in key for key in header.keys()): raise KeyError("You are missing 'DET_YX{}' keys: which are the detector locations of the PSFs") if 'OVERSAMP' not in header.keys(): raise KeyError("You are missing 'OVERSAMP' key: which is the oversampling factor of the PSFs") # Convert header to meta dict header = header.copy(strip=True) header.pop('COMMENT', None) header.pop('', None) header.pop('HISTORY', None) meta = OrderedDict((a, (b, c)) for (a, b, c) in header.cards) ndd = NDData(data, meta=meta, copy=True) # Edit meta dictionary for GriddedPSFLibrary specifics ndd.meta['grid_xypos'] = [((float(ndd.meta[key][0].split(',')[1].split(')')[0])), (float(ndd.meta[key][0].split(',')[0].split('(')[1]))) for key in ndd.meta.keys() if "DET_YX" in key] # from (y,x) to (x,y) if 'oversampling' not in ndd.meta: ndd.meta['oversampling'] = ndd.meta['OVERSAMP'][0] # pull the value # Turn all metadata keys into lowercase ndd.meta = {key.lower(): ndd.meta[key] for key in ndd.meta} # Create model model = GriddedPSFModel(ndd) return model
def to_griddedpsfmodel(HDUlist_or_filename=None, ext_data=0, ext_header=0): """ Create a photutils GriddedPSFModel object from either a FITS file or an HDUlist object. The input must have header keywords "DET_YX{}" and "OVERSAMP" (will already be present if psf_grid() is used to create the file). Parameters ---------- HDUlist_or_filename : HDUList or str Either a fits.HDUList object or a filename of a FITS file on disk ext_data : int Extension of the data in the FITS file ext_header : int Extension of the header in the FITS file Returns ------- model : GriddedPSFModel Photutils object with 3D data array and metadata with specified grid_xypos and oversampling keys """ try: from photutils import GriddedPSFModel except ImportError: raise ImportError("This method requires photutils >= 0.6") if isinstance(HDUlist_or_filename, str): HDUlist = fits.open(HDUlist_or_filename) elif isinstance(HDUlist_or_filename, fits.HDUList): HDUlist = HDUlist_or_filename else: raise ValueError('Input must be a filename or HDUlist') data = HDUlist[ext_data].data header = HDUlist[ext_header].header # If there's only 1 PSF and the data is 2D, make the data 3D for photutils can use it if len(data.shape) == 2 and len(header['DET_YX*']) == 1: data = np.array([data]) # Check necessary keys are there if not any("DET_YX" in key for key in header.keys()): raise KeyError( "You are missing 'DET_YX{}' keys: which are the detector locations of the PSFs" ) if 'OVERSAMP' not in header.keys(): raise KeyError( "You are missing 'OVERSAMP' key: which is the oversampling factor of the PSFs" ) # Convert header to meta dict header = header.copy(strip=True) header.pop('COMMENT', None) header.pop('', None) header.pop('HISTORY', None) meta = OrderedDict((a, (b, c)) for (a, b, c) in header.cards) ndd = NDData(data, meta=meta, copy=True) # Edit meta dictionary for GriddedPSFLibrary specifics ndd.meta['grid_xypos'] = [ ((float(ndd.meta[key][0].split(',')[1].split(')')[0])), (float(ndd.meta[key][0].split(',')[0].split('(')[1]))) for key in ndd.meta.keys() if "DET_YX" in key ] # from (y,x) to (x,y) if 'oversampling' not in ndd.meta: ndd.meta['oversampling'] = ndd.meta['OVERSAMP'][0] # pull the value # Turn all metadata keys into lowercase ndd.meta = {key.lower(): ndd.meta[key] for key in ndd.meta} # Create model model = GriddedPSFModel(ndd) return model