def solve_image(filename, api_key): ast = AstrometryNet() ast.api_key = api_key wcs_header = ast.solve_from_image(filename) return wcs_header
def _perform(self): """ Returns an Argument() with the parameters that depends on this operation. """ self.log.info(f"Running {self.__class__.__name__} action") from astroquery.exceptions import TimeoutError as astrometryTimeout from astroquery.astrometry_net import AstrometryNet ast = AstrometryNet() ast.api_key = self.cfg['Astrometry'].get('api_key', None) solve_timeout = self.cfg['Astrometry'].getint('solve_timeout', 90) nx, ny = self.action.args.kd.pixeldata[0].data.shape if self.action.args.n_objects >= 100: stars = self.action.args.objects[:100] else: stars = self.action.args.objects try: self.log.debug(f" Running astrometry.net solve") wcs_header = ast.solve_from_source_list(stars['x'], stars['y'], nx, ny, solve_timeout=solve_timeout, center_dec=self.action.args.header_pointing.dec.deg, center_ra=self.action.args.header_pointing.ra.deg, radius=0.8, scale_est=0.44, scale_err=0.02, scale_units='arcsecperpix', tweak_order=2, ) except astrometryTimeout as e: self.log.warning('Astrometry solve timed out') return self.action.args except Exception as e: self.log.warning('Astrometry solve failed') self.log.warning(e) return self.action.args if wcs_header == {}: self.log.info(f" Solve failed") return self.action.args self.log.info(f" Solve complete") self.action.args.wcs_header = wcs_header self.action.args.wcs = WCS(wcs_header) # Determine Pointing Error # pixel_scale = np.mean(proj_plane_pixel_scales(self.action.args.wcs))*60*60 r, d = self.action.args.wcs.all_pix2world([nx/2.], [ny/2.], 1) self.action.args.wcs_pointing = c.SkyCoord(r[0], d[0], frame='fk5', equinox='J2000', unit=(u.deg, u.deg), obstime=self.action.args.kd.obstime()) self.action.args.perr = self.action.args.wcs_pointing.separation( self.action.args.header_pointing) self.log.info(f'Pointing error = {self.action.args.perr.to(u.arcmin):.1f}') return self.action.args
def get_astrometry(imgfile, srcs=None, api_key=None, prefix='w', overwrite=False): from astropy.io import fits import astropy.units as u from astropy.coordinates import SkyCoord from astroquery.astrometry_net import AstrometryNet wcsfile = os.path.join(reduxdir, '{}{}'.format(prefix, os.path.basename(imgfile))) if not os.path.isfile(wcsfile) or overwrite: img, hdr = fits.getdata(imgfile, header=True) # Initialize the API. ast = AstrometryNet() if api_key: ast.api_key = api_key #ast.show_allowed_settings() # Get the initial position center based on the header. c = SkyCoord(hdr['OBJCTRA'] + hdr['OBJCTDEC'], unit=(u.hourangle, u.deg)) print('Initial RA, Dec = {:.5f}, {:.5f}'.format( c.ra.value, c.dec.value)) # Query the astrometry.net engine! t0 = time.time() wcshdr = ast.solve_from_source_list(srcs['xcentroid'], srcs['ycentroid'], hdr['naxis1'], hdr['naxis2'], center_ra=c.ra.value, center_dec=c.dec.value, radius=15 / 60.0, scale_type='ev', scale_est=0.8, scale_err=10, scale_units='arcsecperpix', crpix_center=True) print('Total time = {:.3f} min'.format((time.time() - t0) / 60)) # update the original header for key in wcshdr.keys(): if key not in hdr and key != 'COMMENT' and key != 'HISTORY': hdr[key] = wcshdr[key] print('Writing {}'.format(wcsfile)) fits.writeto(wcsfile, img, header=wcshdr, overwrite=True) else: wcshdr = fits.getheader(wcsfile) return wcsfile, wcshdr
def plate_solve(): ast = AstrometryNet() ast.api_key = 'fzyialllobrsoflj' f = open('headers.txt', "w") for filename in glob.glob("*.fits"): hdu = fits.open(filename) print("\nPlate solving for " + filename) file_header = ast.solve_from_image( filename, force_image_upload=True ) # parameters can be adjusted for faster solve hdu[0].header = file_header # create seperate .fits file with different header hdu.writeto(filename.strip('.fits') + '_platesolved.fits') print('\nFinished')
def get_wcs_header(self, file): ast = AstrometryNet() ast.TIMEOUT = 1200 ast.api_key = Constants.api_key print("starting job") wcs = ast.solve_from_image(file, solve_timeout = 1200) print('finished job') if not wcs: print('failed') return WCS(header=wcs)
def upload_file(self): # Creating instance of astrometry.net and API key ast = AstrometryNet() ast.api_key = 'bchkvzadjuswddhg' try_again = True submission_id = None while try_again: try: if not submission_id: # Solves the image from the file path wcs_header = ast.solve_from_image(f'{self.image_path}', force_image_upload=True, submission_id=submission_id, solve_timeout=1000) else: # Time is in seconds. wcs_header = ast.monitor_submission( submission_id, solve_timeout=1000) except TimeoutError as e: # Timeout error, never triggers. Basically useless code since it never triggers during timeout error submission_id = e.args[1] print('\nThere was a timeout error. ( Process took to long ).') print('Astometry.net could also be down at the moment.') else: #! got a result, so terminate try_again = False if wcs_header: # Code to execute when solve succeeds print('\nSuccess! :thumbs_up:') print( '\nTo get the most possible information out of your image please visit the website below.') redirect_to('http://nova.astrometry.net/users/20995') print('\n*********************************************************************************************************************************************') # Looks up target with astroquery then can inp.redirect_to user to the website # to use the aladin lite view to find comp stars, look around, etc. simbad_query() else: #! Code to execute when solve fails print('\n[bold red]Failed[/bold red] to solve.')
def solveplateastrometry(key,data=None,filepath=None): ast = AstrometryNet() ast.api_key = key try_again = True submission_id = None wcs_header = {} while try_again: try: if not submission_id: if not data: print("Requisitando com upload da imagem: ", filepath) wcs_header = ast.solve_from_image(filepath, force_image_upload=True, submission_id=submission_id, solve_timeout=120) print('Com imagem\n',wcs_header) elif isinstance(data,pd.DataFrame) and isinstance(filepath,str): print(data) with fits.open(filepath) as f: w, h = f[0].data.shape wcs_header = ast.solve_from_source_list(data['x'], data['y'], submission_id=submission_id, image_width=w, image_height=h, solve_timeout=120) print('Com table\n',wcs_header) else: wcs_header = ast.monitor_submission(submission_id, solve_timeout=120) print('Buscando algumas vezes\n',wcs_header) except TimeoutError as e: submission_id = e.args[1] else: # got a result, so terminate try_again = False return wcs_header
list = os.listdir(path) fl = [] for fn in list: f = fn.split('.') if f[-1] in ['FIT', 'FITS', 'fit', 'fits']: fl.append(fn) fl.sort() # print (fl) # fl = fl[:1] # #################### BEGIN ast = AstrometryNet() # ast.show_allowed_settings() ast.api_key = "ittzfaqwnrvduhax" if ploting: fig, ax = plt.subplots() log_file = open(path + '//star_phot.log', "w") A_general = [] c_general = [] for fit_file in fl:
import os import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import numpy as np from astropy.io import fits import scipy.signal as sig from scipy import stats import lightkurve as lk import pandas as pd from astroquery.astrometry_net import AstrometryNet ast = AstrometryNet() ast.api_key = 'dnzncgdyolxsukyy' from astroquery.mast import Catalogs from astroquery.vizier import Vizier v = Vizier() from astropy import coordinates from astropy import units as u from astropy.table import Table import kplr client = kplr.API()
def solve_field(img_fn, debug=False): """solve_field Get a plate solution from Astrometry.Net Plate solutions not only provide accurate astrometry of objects in an image, they can also help to identify distortions or rotations in the image not already described in the FITS header. Parameters ---------- img_fn : `str` Filename of the image on which to do a plate solution debug : `bool`, optional Print debugging statements? [Default: False] """ # Instantiate the Astrometry.Net communicator ast = AstrometryNet() # Loop variables try_again = True submission_id = None # Loop until a solution is returned while try_again: try: if not submission_id: # Find objects in the image and send the list to Astrometry.Net wcs_header = ast.solve_from_image(img_fn, submission_id=submission_id) else: # Subsequent times through the loop, check on the submission wcs_header = ast.monitor_submission(submission_id, solve_timeout=120) except aqe_TimeoutError as error: submission_id = error.args[1] except ConnectionError: pass else: # Got a result: Terminate try_again = False # Instantiate a WCS object from the wcs header returned by Astronmetry.Net solved_wcs = WCS(wcs_header) # Read in the FITS file to a CCDData object ccd = CCDData.read(img_fn) if debug: # If desired, print a bunch of diagnostics print(f"\n{ccd.wcs}") print(f"\n{wcs_header}") print(f"\n{solved_wcs}") # Place the WCS object into the .wcs attribute of the CCDData object ccd.wcs = solved_wcs # For good measure, also attempt to update the header with the WCS object ccd.header.update(solved_wcs.to_header()) # Add some history information ccd.header['HISTORY'] = PKG_NAME ccd.header[ 'HISTORY'] = 'Plate solution performed via astroquery.astrometry_net' ccd.header['HISTORY'] = 'Solved WCS added: ' + _savetime() if debug: # Print out the final header before writing to disk print(f"\n{ccd.header}") # Write the CCDData object to disk with the updated WCS information ccd.write(img_fn, overwrite=True)
def _query_astrometry_dot_net(self, astnetkey, cols, rows, xy_table, hints_dict): """ Attempt to get an astrometric solution using astrometry.net Returns a FITS header if successful, an empty dictionary if not. """ # Try to stop astroquery astrometry warnings. This won't work # yet, because the astrometry.net package is using logging instead # of warnings. warnings.filterwarnings("ignore", module='astroquery.astrometry_net') warnings.filterwarnings("ignore", module='astroquery.astrometry_net.core') warnings.filterwarnings("ignore", module='astroquery.astrometry_net.AstrometryNet') wcs = {} image_width = cols image_height = rows ast = AstrometryNet() ast.api_key = astnetkey try_again = True submission_id = None pos_err_pix = 10 # TODO get better estimate from srclist? timeout = 180 sip_order = 0 if self._use_sip: sip_order = 2 self._logger.debug(f'Allowing fitting of SIP distortion polynomial of order {sip_order}') self._logger.warning('Some downstream software, e.g. swarp, may not handle SIP correctly.') # TODO: Robustness... # This block is a modified version of the example online. # - Both the original example and this version seem to fail to try # again. # - If Astrometry.net is not responding we can different exceptions # than just the JSONDecodeError currently handled. while try_again: try: if submission_id is None: self._logger.debug('Submitting astrometry.net solve from source list with {} positions'.format(len(xy_table))) wcs_header = ast.solve_from_source_list(xy_table['X'], xy_table['Y'], image_width, image_height, solve_timeout=timeout, parity=2, positional_error=pos_err_pix, crpix_center=True, publicly_visible='n', tweak_order=sip_order, submission_id=submission_id, **hints_dict) else: self._logger.debug('Monitoring astrometry.net submission {}'.format(submission_id)) try_again = False wcs_header = ast.monitor_submission(submission_id, solve_timeout=timeout) except json.JSONDecodeError as e: err_msg = 'Caught JSONDecodeError. Usually this means Astrometry.net is down or login failed.' self._logger.error(err_msg) raise RuntimeError(err_msg) except astroquery.exceptions.TimeoutError as e: if (submission_id is not None) and (try_again): self._logger.warning(f'Astronomy solve (id={submission_id}) from source list timed out after {timeout} seconds.') submission_id = e.args[1] else: # got a result or failed twice, so terminate try_again = False if wcs_header: self._logger.info('Obtained a WCS header') wcs = wcs_header else: self._logger.error('Astrometry.net submission={} failed'.format(submission_id)) return wcs
from astropy.table import Table from astroquery.astrometry_net import AstrometryNet import astropy.units as u from astropy.coordinates import SkyCoord from astropy.nddata import CCDData, Cutout2D from astro_imutils import imreduce, sub_background, find_all_sources, clean_sources ast = AstrometryNet() ast.api_key = 'guisvvvtcwovgney' def solve(img, clean_cat, ra, dec, binning): x, y, ssum = [], [], [] for s in clean_cat: x.append(s.xcentroid.value) y.append(s.ycentroid.value) ssum.append(s.source_sum) zp = zip(x, y, ssum) zp_sort = sorted(zp, key=lambda t: t[2], reverse=True) x, y, ssum = zip(*zp_sort) image_width = len(im.data[:, 0]) image_height = len(im.data[0, :]) wcs_header = ast.solve_from_source_list(x, y, image_width, image_height, solve_timeout=180, scale_units='arcsecperpix', scale_type='ev', scale_est=0.14 * binning,
import numpy as np from astropy.io.fits import PrimaryHDU, CompImageHDU, ImageHDU from astropy.io import fits from astropy.wcs import WCS import astropy.units as u from astroquery.astrometry_net import AstrometryNet from trail.settings import ASTROMETRY_KEY, ASTROMETRY_TIMEOUT import upload.models as models __all__ = ["HeaderStandardizer", ] logger = logging.getLogger(__name__) ASTRONET_CLIENT = AstrometryNet() if ASTROMETRY_KEY: ASTRONET_CLIENT.api_key = ASTROMETRY_KEY class StandardizeWcsException(Exception): """Exception raised when error in WCS processing Attributes: message -- explanation of the error """ def __init__(self, message="The WCS is not valid"): self.message = message super().__init__(self.message)
def astrometrymaster(self): ''' Runs Astrometry.net on the inputted image/sources table ''' ast = AstrometryNet() ast.api_key = self.getarg('api_key') # Check whether the file contains image or table data, prefer table data upload = True for hdu in fits.open(self.datain.filename): try: ### This try statement works with sextractor catalog files (...sex_cat.fits) # FITS files use big endian, so it must be converted to little endian before it can be used by numpy/pandas tbl = pd.DataFrame(np.array(hdu.data).byteswap(inplace=True).newbyteorder()) # tbl.columns = ['X_IMAGE', 'Y_IMAGE', 'a', 'b', 'c', 'd', 'FLUX'] tbl.columns = ['NUMBER', 'FLUX_APER', 'FLUX_AUTO', 'FLUXERR_AUTO', 'X_IMAGE', 'Y_IMAGE'] # Astrometry.net requires the source table be sorted in descending order of flux tbl = tbl.sort_values(by='FLUX_APER', axis=0, ascending=False) except: try: ### This try statement works with source extracted files containing image data (...SEXT.fits) tbl = pd.DataFrame(np.array(hdu.data).byteswap(inplace=True).newbyteorder()) tbl.columns = ['ID', 'X_IMAGE', 'Y_IMAGE', 'FLUX', 'FLUX_ERR'] tbl = tbl.sort_values(by='FLUX', axis=0, ascending=False) except: pass else: upload = False else: upload = False # Determine the width/height of the image in pixels from the binning try: # The image width and height are stored in NAXIS1 and NAXIS 2 respectively imagew = float(self.datain.getheadval('NAXIS1')) imageh = float(self.datain.getheadval('NAXIS2')) except: # Binning 2 is pretty typical in a lot of cases imagew = 1024. imageh = 1024. self.log.debug('NAXIS1/2 keyword missing from header, assuming image width and height of %d and %d' % (imagew, imageh)) else: self.log.debug('Image width is %d, image height is %d' % (imagew, imageh)) if upload: self.log.debug('File to reduce has not been source extracted, uploading image to Astrometry.net') else: self.log.debug('File to reduce has been source extracted, uploading source table to Astrometry.net') self.log.debug("Now running ast.solve, get comfy this'll take a while") # Check if the header contains RA and Dec try: ra = Angle(self.datain.getheadval('RA'), unit=u.hour).degree dec = Angle(self.datain.getheadval('DEC'), unit=u.deg).degree except: # If the header is missing RA and Dec keywords, attempt to solve without them if upload: self.log.debug('Solving from image without RA/Dec') self.wcs_out = ast.solve_from_image(self.datain.filename, force_image_upload = True, solve_timeout = self.getarg('timeout'), scale_lower = self.getarg('scale_lower'), scale_upper = self.getarg('scale_upper'), scale_units = self.getarg('scale_units')) else: self.log.debug('Solving from source list without RA/Dec') self.wcs_out = ast.solve_from_source_list(x=tbl['X_IMAGE'], y=tbl['Y_IMAGE'], image_width=imagew, image_height=imageh, solve_timeout=self.getarg('timeout')) else: # If the header contains RA and Dec, use them to solve if upload: self.log.debug('Solving from image with RA/Dec') self.wcs_out = ast.solve_from_image(self.datain.filename, force_image_upload = True, ra_key = 'RA', dec_key = 'DEC', solve_timeout = self.getarg('timeout'), radius = self.getarg('radius'), scale_lower = self.getarg('scale_lower'), scale_upper = self.getarg('scale_upper'), scale_units = self.getarg('scale_units')) else: self.log.debug('Solving from source list with RA/Dec') self.wcs_out = ast.solve_from_source_list(x=tbl['X_IMAGE'], y=tbl['Y_IMAGE'], image_width=imagew, image_height=imageh, solve_timeout=self.getarg('timeout'), radius=self.getarg('radius'), center_ra=ra, center_dec=dec) # Check if the solution completed, though it should error if it times out anyway try: self.wcs_out except: self.log.error('Failed to find WCS solution') else: self.log.debug('Web astrometry completed successfully')
def flip_image(image_path, saved_location): """ Flip or mirror the image @param image_path: The path to the image to edit @param saved_location: Path to save the cropped image """ image_obj = Image.open(image_path) rotated_image = image_obj.transpose(Image.FLIP_LEFT_RIGHT) rotated_image.save(saved_location) rotated_image.show() ast = AstrometryNet() ast.api_key = 'XXXXXXXXXXXXXXXX' imagename = sys.argv[1] #image.show() #imagename = "D:/Google Drive/Stellarium DSO image addition/buble_full_P-1.jpg" file, ext = os.path.splitext(imagename) image = Image.open(imagename) print('Unstretching image by raising blackpoint (for Plate Solving)') greyscale = image.copy().convert('L') stars = ImageOps.colorize(greyscale, black="black", white="white", blackpoint=200, whitepoint=255) #stars.show() print('Saving:', file + '_stars.jpg' ) stars.save(file + '_stars.jpg') print('Uploading:', file + '_stars.jpg' )