def register(ref, toshift, method, outdir=None, center=None, size=None, overwrite=False): '''Register and shift images''' hdu_ref = fits.open(ref) hdu_shift = fits.open(toshift) if center is None: # use center of image center = [int(x / 2.) for x in hdu_ref[0].shape] # resize if size is not None: refdat = Cutout2D(hdu_ref[0].data, position=center, size=size).data shiftdat = Cutout2D(hdu_shift[0].data, position=center, size=size).data else: refdat = hdu_ref[0].data shiftdat = hdu_shift[0].data if method == 'point': xoff, yoff = point_align(refdat, shiftdat) elif method == 'extended': xoff, yoff = extended_align(refdat, shiftdat) else: raise (NotImplementedError("method %s unknown" % method)) # shift hdu_shift[0].data = shift.shiftnd(hdu_shift[0].data, (-yoff, -xoff)) hdu_shift[0].header.add_history( '%s - %s' % (os.path.basename(__file__), Time(Time.now(), format='fits'))) hdu_shift[0].header.add_history( '%s - aligned to %s' % (os.path.basename(__file__), os.path.basename(ref))) hdu_shift[0].header.add_history('%s - shift_x: %.3f, shift_y: %.3f' % (os.path.basename(__file__), -xoff, -yoff)) hdu_shift[0].header['ALIGNED'] = (True, 'Image aligned to reference') hdu_shift[0].header['REFALGND'] = (os.path.basename(ref), 'Reference file for alignment') hdu_shift[0].header['SXOFF'] = (-xoff, 'X shift') hdu_shift[0].header['SYOFF'] = (-yoff, 'Y shift') if outdir: #write file and return filename outfile = os.path.join(outdir, os.path.basename(toshift)) with warnings.catch_warnings(): warnings.simplefilter('ignore', VerifyWarning) hdu_shift.writeto(outfile, overwrite=overwrite, output_verify='silentfix') return outfile else: # if outdir is None, return hdu return hdu_shift
def image_snippet(image, center, width=50, axis=None, fig=None, is_mask=False, pad_black=False, **kwargs): """ Display a subsection of an image about a center. Parameters ---------- image : numpy array The full image from which a section is to be taken. center : list-like The location of the center of the cutout. width : int, optional Width of the cutout, in pixels. axis : matplotlib.Axes instance, optional Axis on which the image should be displayed. fig : matplotlib.Figure, optional Figure on which the image should be displayed. is_mask : bool, optional Set to ``True`` if the image is a mask, i.e. all values are either zero or one. pad_black : bool, optional If ``True``, pad edges of the image with zeros to fill out width if the slice is near the edge. """ if pad_black: sub_image = Cutout2D(image, center, width, mode='partial', fill_value=0) else: # Return a smaller subimage if extent goes out side image sub_image = Cutout2D(image, center, width, mode='trim') show_image(sub_image.data, cmap='gray', ax=axis, fig=fig, show_colorbar=False, show_ticks=False, is_mask=is_mask, **kwargs)
def test_copy(self): data = np.copy(self.data) c = Cutout2D(data, (2, 3), (3, 3)) xy = (0, 0) value = 100. c.data[xy] = value xy_orig = c.to_original_position(xy) yx = xy_orig[::-1] assert data[yx] == value data = np.copy(self.data) c2 = Cutout2D(self.data, (2, 3), (3, 3), copy=True) c2.data[xy] = value assert data[yx] != value
def find_zeropoint(BSCatalogue, data, wcs_file, STAR_PHOT=5): ''' Нахождение интенсивности в отсчётах камеры для звезды 0-й звёздной величины. Пересвеченные звёзды не учитываются. Запись полученных параметров (нуль-пункт и его погрешность) в header WCS файла. ''' FLUX_0m = [] BSCatalogue.add_column(Column(np.zeros(len(BSCatalogue))), name='Observ_flux') BSCatalogue.add_column(Column(np.zeros(len(BSCatalogue))), name='Flux_0m') for i in BSCatalogue: x, y = i['x_obs'], i['y_obs'] m = i['vmag_atmosph'] STAR_data = Cutout2D(data, (x, y), (2 * STAR_PHOT + 1, 2 * STAR_PHOT + 1)).data # plt.imshow(STAR_data) # plt.show() ma = np.max(STAR_data) if ma > 200 and np.sum(STAR_data > 0.9 * ma) > 12: continue i['Observ_flux'] = check.photometry(STAR_data) FLUX_0m.append(i['Observ_flux'] * (2.512**m)) i['Flux_0m'] = FLUX_0m[-1] FLUX_0m = np.array(FLUX_0m) with fits.open(wcs_file, mode='update') as hdul: header = hdul[0].header header['zeropoint'] = FLUX_0m.mean() header['sigma_zeropoint'] = FLUX_0m.std() hdul.flush() return BSCatalogue
def Imager(imagefile, ra, dec): hdu_list = fits.open(imagefile) hdu_list.info() image_data = hdu_list[0].data # grab wcs from imageslice w = WCS(hdu_list[0].header) size = u.Quantity((120, 120), u.pixel) c = SkyCoord(ra, dec, frame='fk5', unit='deg') # RESHAPE DATA FOR PROPER FORMAT shape = (image_data.shape) image_data = np.reshape(image_data, (shape[2], shape[3])) hdu_list.close() # make wcss frame like in cutout wcss = WCS(naxis=2) wcss.wcs.ctype = ['RA---SIN', 'DEC--SIN'] wcss.wcs.crval = [w.wcs.crval[0], w.wcs.crval[1]] wcss.wcs.crpix = [w.wcs.crpix[0], w.wcs.crpix[1]] wcss.wcs.cdelt = [w.wcs.cdelt[0], w.wcs.cdelt[1]] # plot and save the data try: plt.figure(figsize=(10, 10)) cutout1 = Cutout2D(image_data, c, size, wcs=wcss) plt.imshow(cutout1.data, origin='lower') except: # plot and save the data print 'failed centering' plt.figure(figsize=(10, 10)) plt.imshow(image_data, origin='lower') plt.colorbar() plt.savefig(imagefile.replace(".fits", ".png")) plt.show()
def test_cutout_partial_overlap_fill_value(self): fill_value = -99 c = Cutout2D(self.data, (0, 0), (3, 3), mode='partial', fill_value=fill_value) assert c.data.shape == (3, 3) assert c.data[1, 1] == 0 assert c.data[0, 0] == fill_value
def __dev_fits(self, options, id): time.sleep(options['exposure']) sample_fits = [ x for x in os.listdir(os.environ['SAMPLE_FITS_PATH']) if x.lower().endswith('.fits') ] file_index = int(time.time() * 1000) % len(sample_fits) dest_filename = '{}.fits'.format(id) source_path = os.path.join(os.environ['SAMPLE_FITS_PATH'], sample_fits[file_index]) dest_path = os.path.join(self.settings.camera_tempdir, dest_filename) logger.debug('{} ==> {}'.format(source_path, dest_path)) if 'roi' in options and options['roi']: roi = options['roi'] with fits.open(source_path) as hdu: data = hdu[0].data full_height, full_width = hdu[0].shape logger.debug('shape: {}x{}'.format(full_width, full_height)) cutout_size = (roi['height'], roi['width']) cutout_center = (roi['x'] + roi['width'] / 2, roi['y'] + roi['height'] / 2) cutout = Cutout2D(data, cutout_center, cutout_size, copy=True) hdu[0].data = cutout.data hdu.writeto(dest_path) else: shutil.copyfile(source_path, dest_path, follow_symlinks=True) image = self.__new_image_to_list(dest_filename, id) return image.to_map(for_saving=False)
def Seeing(data, r=11): from astropy.stats import sigma_clipped_stats from photutils.detection import DAOStarFinder from astropy.nddata.utils import Cutout2D # Source detection mean, median, std = sigma_clipped_stats(data, sigma=3) starfind = DAOStarFinder(fwhm=4.0, threshold=5. * std, exclude_border=True, sky=median) sources = starfind(data - median) x = sources['xcentroid'] y = sources['ycentroid'] # FWHM over all the detected sources fwhm = [] for i in range(len(x)): cut = Cutout2D(data, [x[i], y[i]], r, mode='partial') sec = cut.data xc, yc = cut.to_cutout_position([x[i], y[i]]) fwhm.append(FWHM(sec, xc, yc)) return np.array(fwhm)
def BSC_observ_flux(BSCatalogue, data, STAR_PHOT=5.): ''' Получение видимого потока от звёзд. Пересвеченные звёзды удаляются из каталога. ''' BSCatalogue.add_column( Column(np.zeros(len(BSCatalogue))), name='Observ_flux') j = 0 while j < len(BSCatalogue): i = BSCatalogue[j] x, y = i['x'], i['y'] STAR_data = Cutout2D( data, (x, y), (2*STAR_PHOT + 1, 2*STAR_PHOT + 1)).data ma = np.max(STAR_data) if ma > 200 and np.sum(STAR_data > 0.9*ma) > 12: BSCatalogue.remove_row(j) continue i['Observ_flux'] = photometry(STAR_data) # if i['Observ_flux'] < i['Flux'] - i['sigma_Flux']*2: # plt.imshow(STAR_data) # plt.title('r = ' + str(((x-960)**2 + (y-540)**2)**0.5) + '; FLUX = ' + str(i['Observ_flux'])) # plt.show() j += 1 return BSCatalogue
def make_triplet_for_braai(ra, dec, new_aligned, ref_aligned, sub_aligned, old_norm=False): # aligned images are db.CalibratableImages that have north up, east left from astropy.coordinates import SkyCoord from tensorflow.keras.utils import normalize as tf_norm from astropy.nddata.utils import Cutout2D triplet = np.zeros((63, 63, 3)) coord = SkyCoord(ra, dec, unit='deg') for i, img in enumerate([new_aligned, ref_aligned, sub_aligned]): cutout = Cutout2D(img.data, coord, size=63, mode='partial', fill_value=0., wcs=img.wcs) if old_norm: triplet[:, :, i] = tf_norm(cutout.data) else: triplet[:, :, i] = cutout.data / np.linalg.norm(cutout.data) return triplet
def crop_560MHz_to1400MHz(imagename, ref_imagename): print(' Cropping 560 MHz image to 1400 MHz FOV...') # Adapted from https://docs.astropy.org/en/stable/nddata/utils.html ref_hdu = fits.open(ref_imagename)[0] # the 1400mhz image hdu = fits.open(imagename)[0] wcs = WCS(hdu.header) # cutout to 1400 MHz area. hard coded, since 1400 MHz beam is 2.5 times smaller than 560 MHz beam. x_size = ref_hdu.header['NAXIS1'] x_pixel_deg = ref_hdu.header[ 'CDELT2'] # CDELT1 is negative, so take positive one size = ( x_size * x_pixel_deg * u.degree, x_size * x_pixel_deg * u.degree ) # angular size of cutout, using astropy coord. approx 32768*0.6 arcseconds. position = SkyCoord(hdu.header['CRVAL1'] * u.degree, hdu.header['CRVAL2'] * u.degree) # RA and DEC of beam PB pointing cutout = Cutout2D(hdu.data, position=position, size=size, mode='trim', wcs=wcs, copy=True) hdu.data = cutout.data # Put the cutout image in the FITS HDU hdu.header.update( cutout.wcs.to_header()) # Update the FITS header with the cutout WCS hdu.writeto(imagename[:-5] + '_CropTo1400mhzFOV.fits', overwrite=True) # Write the cutout to a new FITS file
def make_images(field, imgpath, size): full_hdu, full_wcs = load_image(imgpath) full_header = full_hdu.header img_data = full_hdu.data[0, 0, :, :] for source in field: src_coord = SkyCoord(source['ra'], source['dec'], unit=(u.hourangle, u.deg)) cutout = Cutout2D(img_data, position=src_coord, size=size, wcs=full_wcs) if 'name' in field.keys(): outfile = '%s.fits' % source['name'] else: outfile = '%s.fits' % (src_coord.to_string(style='hmsdms')) # Put the cutout image in the FITS HDU hdu = fits.PrimaryHDU(data=cutout.data) hdu.header = full_header # Update the FITS header with the cutout WCS hdu.header.update(cutout.wcs.to_header()) # Write the cutout to a new FITS file hdu.writeto(outfile, overwrite=True)
def find_CANDELS_sky_patch(bands, field): looking_for_input = True while looking_for_input: skypatches = [] input_coord = None try: sources = sources_dfs[field] source = sources.iloc[np.random.randint(0, sources.shape[0])] coord = SkyCoord(ra=source.RA * u.deg, dec=source.DEC * u.deg) for band, filter in zip(bands, FIELDS[field]): #gal_img = fits.getdata(f'/data/captain/MERGERS/SKIRT/TNG50-1/PMxSF/TESTS/{filter}/30_100453_oct_1.fits') wcs = WCS_MEMORY[field][ filter] #header = fits.getheader(f'/home/ppxlf2/CANDELS/{field}/{FIELDS[field][filter]["fits_filename"]}.fits') data = FIELDS[field][filter][ 'data'] #fits.getdata(f'/home/ppxlf2/CANDELS/{field}/{FIELDS[field][filter]["fits_filename"]}.fits', memmap=True) #wcs = WCS(header) #wcs.sip = None if input_coord is None: cutout = Cutout2D(data, position=coord, size=512, wcs=wcs) if np.all(cutout.data == 0): raise ValueError('Empty Patch of the Sky') input_coord = search_input_position(cutout) cutout = Cutout2D(data, position=input_coord, size=256, wcs=wcs) skypatches.append(cutout.data) except ValueError as e: print(e) continue break return skypatches, field, input_coord
def __init__(self, gid, field, flter, nearby_fitting_region, nearby_gids = None): if not (field == 'S' or field == 'N'): raise Exception('Field must be S or N.') if not type(flter) == str: raise Exception('Filter must be string.') self.gid = gid self.field = field self.flter = flter self.nearby_fitting_region = nearby_fitting_region if self.flter == '850': if self.field == 'N': self.fitsfile = 'GOODS-N_acsz_sci_sub.fits' self.fullfield = 'North' if self.field == 'S': self.fitsfile = 'goodss_3dhst.v4.0.F850LP_orig_sci.fits' self.fullfield = 'South' else: if self.field =='S': self.fitsfile = 'goodss_3dhst.v4.0.F'+flter+'W_orig_sci.fits' self.fullfield = 'South' if self.field =='N': self.fitsfile = 'goodsn_3dhst.v4.0.F'+flter+'W_orig_sci.fits' self.fullfield = 'North' ### CATALOG ### if (field == 'S') or (field == 'South'): catalog = '/Users/rosaliaobrien/research/website/catalogs/goodss_3dhst.v4.4.cat' if (field == 'N') or (field == 'North'): catalog = '/Users/rosaliaobrien/research/website/catalogs/goodsn_3dhst.v4.4.cat' self.cat = ascii.read(catalog) ### GET SKY ESTIMATE ### if not nearby_gids == None: xmin, xmax, ymin, ymax = self.get_boundaries(nearby_gids) path = '/Users/rosaliaobrien/research/GALFIT_CLEAR/running_GALFIT/'+self.fullfield+'/'+self.flter+'/' skydata = fits.open(path+self.fitsfile)[0].data xmid = (xmin+xmax)/2 ymid = (ymin+ymax)/2 cutout = Cutout2D(skydata, (xmid, ymid), (400, 400), copy=True, mode='partial') masked_cutout = make_source_mask(cutout.data, snr = 1.5, npixels=10, dilate_size=11) cutout.data[masked_cutout] = np.nan self.scidata = cutout.data sigma_clip = SigmaClip(sigma=3) bkg = SExtractorBackground(sigma_clip) rms = MADStdBackgroundRMS(sigma_clip) self.sky_value = bkg.calc_background(cutout.data) self.rms_value = rms.calc_background_rms(cutout.data)
def cutout_image(filename,ra,dec,size): hdu = fits.open(filename)[1] wcs = WCS(hdu.header) image_size = (size*u.arcsec, size*u.arcsec) position = SkyCoord(ra*u.degree , dec*u.degree) cutout = Cutout2D(hdu.data, position, image_size, wcs=wcs) return cutout
def spin_and_trim(imlist, wcsrefimname, trimfrac=0.4, trimdir='DIA_TRIM', verbose=False): """ Rotate images to match the WCS of the WCS reference image (spin) and then cut off a fraction of the outer region of the image (trim). Returns a list of the trimmed images. """ if verbose: print('Spinning Input Images: ' + str(imlist)) print("to match WCS Ref image: " + wcsrefimname) print("and trimming by : %i pct" % (trimfrac * 100)) if not os.path.exists(trimdir): os.makedirs(trimdir) trimmed_image_list = [] hdr_imref = fits.getheader(wcsrefimname) wcs_imref = WCS(hdr_imref) for imname in list(imlist) + [wcsrefimname]: imname_trimmed = os.path.join( trimdir, os.path.basename(imname).replace('.fits', '_trim.fits')) if os.path.isfile(imname_trimmed): print("%s exists. Skipping trimming." % imname_trimmed, file=sys.stderr) continue if verbose: print("Reprojecting %s to x,y frame of %s " % (imname, wcsrefimname), file=sys.stderr) im = fits.open(imname) if imname != wcsrefimname: array, footprint = reproject_interp(im[0], hdr_imref) else: # WCS Ref image does not need reprojection array = im[0].data # Trim off the outer trimfrac to reduce chances of NaN errors due to # empty array segments after rotation (also speeds up DIA processing) arraysize = array.shape cutout = Cutout2D(array, position=[arraysize[1] / 2., arraysize[0] / 2.], size=[ round(arraysize[1] * (1 - trimfrac)), round(arraysize[0] * (1 - trimfrac)) ], wcs=wcs_imref) # save reprojected-and-trimmed image: im[0].data = cutout.data im[0].header.update(cutout.wcs.to_header()) im.writeto(imname_trimmed, output_verify='fix+warn') im.close() trimmed_image_list.append(imname_trimmed) return (trimmed_image_list)
def make_cutout(data): return Cutout2D( data, centre_pos, cutout_size, wcs=frame_wcs, mode='partial', copy=True, )
def test_skycoord(self): c = Cutout2D(self.data, self.position, (3, 3), wcs=self.wcs) skycoord_original = self.position.from_pixel(c.center_original[1], c.center_original[0], self.wcs) skycoord_cutout = self.position.from_pixel(c.center_cutout[1], c.center_cutout[0], c.wcs) assert_quantity_allclose(skycoord_original.ra, skycoord_cutout.ra) assert_quantity_allclose(skycoord_original.dec, skycoord_cutout.dec)
def Centroid(data, coords, size=7, method='1dg', mask=None): """ Entrada: imagen, lista de coordenadas. Busca el centroide en una region de radio "r" entorno a la posicion dada en "coords". Salida: array con las posisiones ajustadas y distancia entre las posisiones "d" Parameters ---------- data : TYPE DESCRIPTION. coords : numpy array n coordinates in a (n,2) numpy array. size : number, optional Size in pixels of the section containing the start where perform the centroid. The default is 3. method : photutils.centroid com: Calculates the object “center of mass” from 2D image moments. quadratic: Calculates the centroid by fitting a 2D quadratic polynomial to the data. 1dg: Calculates the centroid by fitting 1D Gaussians to the marginal x and y distributions of the data. 2dg: Calculates the centroid by fitting a 2D Gaussian to the 2D distribution of the data. Returns ------- None. """ # ============================================================================= # Paquetes utilizados # ============================================================================= from photutils.centroids import centroid_com, centroid_quadratic, centroid_1dg, centroid_2dg from astropy.nddata.utils import Cutout2D from astropy.stats import sigma_clipped_stats # Diccionario con los distintos metodos de centrados cent = { 'com': centroid_com, 'quadratic': centroid_quadratic, '1dg': centroid_1dg, '2dg': centroid_2dg } # Vamos a definir una seccion de los datos cut = Cutout2D(data, coords, size=size) sec = cut.data #Calculamos el cielo solo dentro de la dregion selectionada y lo restamos median = sigma_clipped_stats(sec, sigma=3.0)[1] sec = sec - median x_s, y_s = cent[method](sec, mask=mask) fit_coords = cut.to_original_position([x_s, y_s]) return fit_coords
def test_size_pixel(self): """ Check size in derived pixel units. """ size = 0.3 * u.arcsec / (0.1 * u.arcsec / u.pixel) c = Cutout2D(self.data, (2, 2), size) assert c.data.shape == (3, 3) assert c.data[0, 0] == 5 assert c.slices_original == (slice(1, 4), slice(1, 4)) assert c.slices_cutout == (slice(0, 3), slice(0, 3))
def source_detection(ccd, fwhm=3.0, sigma=3.0, iters=5, threshold=5.0, find_fwhm=True): """ Returns an astropy table containing the position of sources within the image. Parameters ---------------- ccd : numpy.ndarray The CCD Image array. fwhm : float, optional Full-width half-max of stars in the image. sigma : float, optional. The number of standard deviations to use as the lower and upper clipping limit. iters : int, optional The number of iterations to perform sigma clipping threshold : float, optional. The absolute image value above which to select sources. find_fwhm : bool, optional If ``True``, estimate the FWHM of each source by fitting a 2D Gaussian to it. Returns ----------- sources an astropy table of the positions of sources in the image. If `find_fwhm` is ``True``, includes a column called ``FWHM``. """ data = ccd mean, median, std = sigma_clipped_stats(data, sigma=sigma, maxiters=iters) daofind = DAOStarFinder(fwhm=fwhm, threshold=threshold * std) sources = daofind(data - median) if find_fwhm: fwhm_fit = [] for source in sources: x = source['xcentroid'] y = source['ycentroid'] cutout = Cutout2D(data, (x, y), 5 * fwhm) fit = fit_2dgaussian(cutout.data) fwhm_fit.append(gaussian_sigma_to_fwhm * (fit.x_stddev + fit.y_stddev) / 2) sources['FWHM'] = fwhm_fit return sources
def test_crpix_maps_to_crval(self): w = Cutout2D(self.data, (0, 0), (3, 3), wcs=self.sipwcs, mode='partial').wcs pscale = np.sqrt(proj_plane_pixel_area(w)) assert_allclose( w.wcs_pix2world(*w.wcs.crpix, 1), w.wcs.crval, rtol=0.0, atol=1e-6 * pscale ) assert_allclose( w.all_pix2world(*w.wcs.crpix, 1), w.wcs.crval, rtol=0.0, atol=1e-6 * pscale )
def PlotterFunction(image_data, c, wcss, ids, size, database): print c print wcss print size print image_data # GET CUTOUT AND PLOT IT plt.figure(figsize=(10, 10)) cutout1 = Cutout2D(image_data, c, size, wcs=wcss) plt.imshow(cutout1.data, origin='lower') plt.colorbar() plt.savefig(str(ids) + "cutout_" + database + ".png") plt.show()
def makebeam(self, xpixels, ypixels, beamSize, cellSize=1, cent=None): if not cent: cent = [xpixels / 2, ypixels / 2] beamSize = np.array(beamSize) st_dev = beamSize[0:2] / cellSize / 2.355 rot = beamSize[2] if np.tan(np.radians(rot)) == 0: dirfac = 1 else: dirfac = np.sign(np.tan(np.radians(rot))) x, y = np.indices((int(xpixels), int(ypixels)), dtype='float') x -= cent[0] y -= cent[1] a = (np.cos(np.radians(rot)) ** 2) / (2 * st_dev[1] ** 2) + (np.sin(np.radians(rot)) ** 2) / \ (2 * (st_dev[0] ** 2)) b = (dirfac * (np.sin(2 * np.radians(rot)) ** 2) / (4 * st_dev[1] ** 2)) + ((-1 * dirfac) * \ (np.sin(2 * np.radians(rot)) ** 2) / (4 * st_dev[0] ** 2)) c = (np.sin(np.radians(rot)) ** 2) / (2 * st_dev[1] ** 2) + (np.cos(np.radians(rot)) ** 2) / \ (2 * st_dev[0] ** 2) psf = np.exp(-1 * (a * x ** 2 - 2 * b * (x * y) + c * y ** 2)) ### Trim around high values in the psf, to speed up the convolution ### psf[psf < 1e-5] = 0 # set all kernel values that are very low to zero # sum the psf in the beam major axis if 45 < beamSize[2] < 135: flat = np.sum(psf, axis=1) else: flat = np.sum(psf, axis=0) idx = np.where(flat > 0)[0] # find the location of the non-zero values of the psf newsize = (idx[-1] - idx[0]) # the size of the actual (non-zero) beam is this if newsize % 2 == 0: newsize += 1 # add 1 pixel just in case else: newsize += 2 # if necessary to keep the kernel size odd, add 2 pixels trimmed_psf = Cutout2D(psf, (cent[1], cent[0]), newsize).data # cut around the psf in the right location return trimmed_psf
def test_cutout_with_nddata_as_input(self): # This is essentially a copy/paste of test_skycoord with the # input a ccd with wcs attribute instead of passing the # wcs separately. ccd = CCDData(data=self.data, wcs=self.wcs, unit='adu') c = Cutout2D(ccd, self.position, (3, 3)) skycoord_original = self.position.from_pixel(c.center_original[1], c.center_original[0], self.wcs) skycoord_cutout = self.position.from_pixel(c.center_cutout[1], c.center_cutout[0], c.wcs) assert_quantity_allclose(skycoord_original.ra, skycoord_cutout.ra) assert_quantity_allclose(skycoord_original.dec, skycoord_cutout.dec)
def _get_image(self, time=None): ''' Get the image at a given time (defaulting to the first time), by pulling it from the source frame. ''' bigimage, actual_time = self.source._get_image(time) self.cutout = Cutout2D(bigimage, self.position, self.size, mode='partial') cutoutimage = self.cutout.data return cutoutimage, actual_time
def cutout(self, position, size): """ Cut out rectangular piece of a image. See :ref:`image-cutpaste` for more information how to cut and paste sky images. Parameters ---------- position : `~astropy.coordinates.SkyCoord` Position of the center of the image to cut out. size : int, array-like, `~astropy.units.Quantity` The size of the cutout array along each axis. If ``size`` is a scalar number or a scalar `~astropy.units.Quantity`, then a square cutout of ``size`` will be created. If ``size`` has two elements, they should be in ``(ny, nx)`` order. Scalar numbers in ``size`` are assumed to be in units of pixels. ``size`` can also be a `~astropy.units.Quantity` object or contain `~astropy.units.Quantity` objects. Such `~astropy.units.Quantity` objects must be in pixel or angular units. For all cases, ``size`` will be converted to an integer number of pixels, rounding the the nearest integer. See the ``mode`` keyword for additional details on the final cutout size. .. note:: If ``size`` is in angular units, the cutout size is converted to pixels using the pixel scales along each axis of the image at the ``CRPIX`` location. Projection and other non-linear distortions are not taken into account. Returns ------- cutout : `~gammapy.image.SkyImage` Cut out image. """ cutout = Cutout2D( self.data, position=position, wcs=self.wcs, size=size, copy=True, ) return self.__class__( name=self.name, data=cutout.data, wcs=cutout.wcs, unit=self.unit, )
def select_cutout(image, wcs): #I'm looking for how many pointings are in the mosaic #I don't know if it is always accurate nrow = image.shape[0] // 300. ncol = image.shape[1] // 300. #measuring the exact width of a row and of a column drow = image.shape[0] / nrow dcol = image.shape[1] / ncol #I'm showing the image to select the correct section #I'm picking the center with a mouse click (maybe) fig, ax = plt.subplots(1, 1) interval = vis.PercentileInterval(99.9) vmin, vmax = interval.get_limits(image) norm = vis.ImageNormalize(vmin=vmin, vmax=vmax, stretch=vis.LogStretch(1000)) ax.imshow(image, cmap=plt.cm.Greys, norm=norm, origin='lower') for x in np.arange(0, image.shape[1], dcol): ax.axvline(x) for y in np.arange(0, image.shape[0], drow): ax.axhline(y) def onclick(event): ix, iy = event.xdata, event.ydata col = ix // 300. row = iy // 300. print(col, row) global x_cen, y_cen x_cen = 150 + 300 * (col) #x of the center of the quadrans y_cen = 150 + 300 * (row) #y of the center of thw quadrans print('x: {:3.0f}, y: {:3.0f}'.format(x_cen, y_cen)) if event.key == 'q': fig.canvas.mpl_disconnect(cid) cid = fig.canvas.mpl_connect('button_press_event', onclick) plt.show() nrow = image.shape[0] // 300. ncol = image.shape[1] // 300. print(image.shape[0] / nrow) x = int(x_cen) y = int(y_cen) print(x, y) cutout = Cutout2D(image, (x, y), size=(image.shape[0] / nrow - 20) * u.pixel, wcs=wcs) return cutout
def get_montaged_cutout(subject_id): gal = gu.get_galaxy(subject_id) ra, dec = gu.metadata.loc[subject_id][['ra', 'dec']] centre_pos, dx, dy = get_cutout_params(gal, ra, dec) montage_fits = fits.open(get_frames(subject_id=subject_id)[1]) montage_cutout = Cutout2D( montage_fits[0].data, centre_pos, (dx, dy), wcs=WCS(montage_fits[0]), mode='partial', copy=True, ) return montage_cutout
def build_overlay(ephemerides, lower_sigma=1, upper_sigma=7, cmap='plasma', radius=None, format='png'): position = ephemerides.first.coordinate img = fits.open(_fits_index.closest_image(position).abs_fn, mmap=True) cutout = Cutout2D(img[0].data, position, size=radius * 2, wcs=WCS(img[0].header)) # wcs = WCS(img[0].header) # image_data = img[0].data wcs = cutout.wcs image_data = cutout.data buf = BytesIO() fig = Figure() FigureCanvas(fig) ax = fig.add_subplot(111, projection=wcs) mean = np.mean(image_data) stdev = np.std(image_data) upper = mean + upper_sigma * stdev lower = mean - lower_sigma * stdev ax.imshow(image_data, cmap=cmap, norm=LogNorm(vmin=lower, vmax=upper)) def add_marker(eph, color, marker): ax.scatter(eph.RA, eph.decl, marker=marker, transform=ax.get_transform('fk5'), s=30, edgecolor=color, facecolor='none') for eph in ephemerides.rest: add_marker(eph, 'red', '.') add_marker(ephemerides.first, 'green', 'X') fig.savefig(buf, format=format, dpi=200) return buf.getvalue()