Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Commit

Permalink
Add --timeout option
Browse files Browse the repository at this point in the history
This option sets the time limit before Astrometry.net gives up trying
to find the astrometric solution for each FITS image. This is exactly
what the --cpulimit option of solve-field does, but there is a (known)
bug that causes it to be ignored unless the 'inparallel' option is set
in the configuration file (astrometry.cfg). Until this is fixed, use
the 'timeout' argument of subprocess.call() — it was added in Python
3.3, so we need the module 'subprocess32', a backport for use on 2.x.

astrometry/usermanual#9
https://groups.google.com/forum/#!topic/astrometry/gyWYg3bQmZ0

This merges branch 'add-timeout-option'
  • Loading branch information
Víctor Terrón committed Sep 4, 2014
2 parents 0e0e81d + c64d98d commit bddfacd
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
60 changes: 53 additions & 7 deletions astrometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,19 @@
import optparse
import os
import shutil
import subprocess
import sys
import tempfile
import warnings

# The 'timeout' argument of subprocess.call() was added in version 3.3.
# In previous versions we need to use 'subprocess32', a backport of the
# subprocess module from Python 3.2/3.3 for use on 2.x.

if sys.version_info < (3, 3):
import subprocess32 as subprocess
else:
import subprocess

# LEMON modules
import customparser
import defaults
Expand Down Expand Up @@ -67,7 +75,19 @@ def __init__(self, path):
def __str__(self):
return "%s: could not solve field" % self.path

def astrometry_net(path, ra = None, dec = None, radius = 1, verbosity = 0):
class AstrometryNetTimeoutExpired(AstrometryNetUnsolvedField):
""" Raised if the Astrometry.net timeout was reached """

def __init__(self, path, timeout):
self.path = path
self.timeout = timeout

def __str__(self):
msg = "%s: could not solve field in less than %d seconds"
return msg % (self.path, self.timeout)

def astrometry_net(path, ra = None, dec = None,
radius = 1, verbosity = 0, timeout = None):
""" Do astrometry on a FITS image using Astrometry.net.
Use a local build of the amazing Astrometry.net software [1] in order to
Expand Down Expand Up @@ -109,10 +129,14 @@ def astrometry_net(path, ra = None, dec = None, radius = 1, verbosity = 0):
Both the right ascension and declination must be given in order
for this feature to work. The three arguments must be expressed
in degrees.
verbosity - the verbosity level. The higher this value, the 'chattier'
Astrometry.net will be. Most of the time, a verbosity other
than zero, the default value, is only needed for debugging.
timeout - the maximum number of seconds that Astrometry.net spends on the
image before giving up and raising AstrometryNetTimeoutExpired.
Note that the backend configuration file (astrometry.cfg) puts a
limit on the CPU time that is spent on an image: this can reduce
that value but not increase it.
"""

Expand Down Expand Up @@ -171,7 +195,7 @@ def astrometry_net(path, ra = None, dec = None, radius = 1, verbosity = 0):
args.append('-%s' % ('v' * verbosity))

try:
subprocess.check_call(args)
subprocess.check_call(args, timeout = timeout)

# .solved file must exist and contain a binary one
with open(solved_file, 'rb') as fd:
Expand All @@ -185,6 +209,8 @@ def astrometry_net(path, ra = None, dec = None, radius = 1, verbosity = 0):
# If .solved file doesn't exist or contain one
except (IOError, AstrometryNetUnsolvedField):
raise AstrometryNetUnsolvedField(path)
except subprocess.TimeoutExpired:
raise AstrometryNetTimeoutExpired(path, timeout)
finally:
methods.clean_tmp_files(output_dir)

Expand All @@ -208,6 +234,17 @@ def astrometry_net(path, ra = None, dec = None, radius = 1, verbosity = 0):
"pointing, or when they do but it is deemed to be "
"entirely unreliable")

parser.add_option('--timeout', action = 'store', type = 'int',
dest = 'timeout', default = 600,
help = "the maximum number of seconds that may be spent "
"attempting to find the astrometric solution of a FITS "
"image. If this time limit is exceeded, we give up and no "
"solution for the image is saved to the output directory. "
"Note, however, that Astrometry.net's backend configuration "
"file (astrometry.cfg) puts a limit on the CPU time that is "
"spent on an image: this option can reduce this value but "
"not increase it. [default: %default]")

parser.add_option('--suffix', action = 'store', type = 'str',
dest = 'suffix', default = 'a',
help = "string to be appended to output images, before "
Expand Down Expand Up @@ -334,12 +371,21 @@ def main(arguments = None):
kwargs = dict(ra = ra,
dec = dec,
radius = options.radius,
verbosity = options.verbose)
verbosity = options.verbose,
timeout = options.timeout)

try:
output_path = astrometry_net(img.path, **kwargs)
except AstrometryNetUnsolvedField:
msg = "%s did not solve. Ignored." % img.path

except AstrometryNetUnsolvedField, e:

# A subclass of AstrometryNetUnsolvedField
if isinstance(e, AstrometryNetTimeoutExpired):
msg = "%s exceeded the timeout limit. Ignored."
else:
msg = "%s did not solve. Ignored."

msg %= img.path
print style.prefix + msg
warnings.warn(msg, RuntimeWarning)
continue
Expand Down
2 changes: 1 addition & 1 deletion lemon-completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ _lemon_mosaic()
_lemon_astrometry()
{
local opts
opts="--radius --blind --suffix --verbose --rak --deck"
opts="--radius --blind --timeout --suffix --verbose --rak --deck"

if [[ ${cur} == -* ]]; then
_match "${opts}"
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ uncertainties>=2.4.1
unittest2>=0.5.1
montage-wrapper>=0.9.7
requests>=2.0.1
subprocess32>=3.2.6

0 comments on commit bddfacd

Please sign in to comment.