Add log_uncaught_exceptions() decorator

This decorator catches any uncaught subclass of Exception raised by
the decorated function and logs it with level DEBUG. This one is the
lowest built-in severity level, which means that these messages are
not tracked by default. This decorator is intended to be mainly used,
if not only, to monkey-patch third-party code that raises a non-fatal
exception which we prefer to ignore except when diagnosing problems.
Ignore occasional warning printed by PyRAF's qphot — now for real!

The idea of using a context manager to suppress the warning message
printed to the standard error because of an uncaught exception in
Subprocess.__del__() (commit 251025303f4bc5) turned out to be quite
a blunder: I have learned the hard way that there are no guarantees
regarding when or even whether __del__() will be called. This means
that the warning message is not suppressed if the object happens to
be destroyed outside the with statement.

Use the methods.log_uncaught_exceptions() decorator to monkey-patch
pyraf.subproc.SubprocessError.__del__(), so that (independently of
when it is called), in case an exception is raised it is caught and
the warning message logged with level DEBUG instead of printed to
the standard error.
Revert "Add ignore_del_exceptions context manager"

A context manager is probably one of the worst ways to (attempt to)
suppress a warning message printed to the standard error because of an
uncaught exception in __del__() — we do not know when or even whether
it will be called, so there is no guarantee that the exception will be
raised within the with statement.

This reverts commit 7fd496fbd862396399928149a073cfe5fad821b8.
Raise the appropriate exception if SCAMP is not installed
Convert read-only variables to upper case

The variables 'aclient_command' and 'scamp_command' are constants,
defining the name of executables (CDSclient and SCAMP, respectively)
and never being modified. Therefore, they would be better written in
all capital letters with underscores separating words, as per PEP 8.
Rename unused variable 'ext' to '_'
Add support for multi-extension FITS files to sextractor()

By default, SExtractor runs on all the extensions in a multi-extension
FITS file, which may lead to subtle and hard-to-debug problems. For
example, the FITS images that we download from the STScI Digitized Sky
Survey for the unit tests have a second extension that contains an
(undocumented) table: running SExtractor on it will give us a series
of false detected sources which are, of course, impossible to match
against any reference catalog.

In order to avoid obscure situations like this, and since the images
with which we are going to work are expected to be single-extension,
force SExtractor to always run on a specific extension. Which one is
specified by the new parameter 'ext', which defaults to zero.
Raise TypeError if 'ext' is not an integer

Accepting a floating point number as an index is dangerous, as it is
silently cast to integer and, for example, 3.95 gets truncated to
three. This may be one of those rare cases in which it is not easier
(nor convenient) to ask forgiveness than permission: we better raise
TypeError if the index 'ext' is not an integer, even if it is a float
with integer value, such as 3.0.
Update unit test for sextractor() with the parameter 'ext'
Add the parameter 'ext' to scamp()
Move FITSImage.ahead_file() to the astromatic module

The external header file needed by SCAMP to do astrometry is, not
surprisingly, only used in one function: scamp(). Therefore, there is
not much point in having the code that generates the file as a method
of the FITSImage class — it belongs to the astromatic module, along
with our high-level wrappers of SExtractor, SCAMP and SWarp.
Change unit of parameter 'scale' to arcsec/pixel

The pixel size of the FITS image must be written to the SCAMP external
header file in degrees per pixel, and therefore that is the scale that
ahead_file() expects. However, all the other functions that take the
scale as an argument use arcseconds per pixel, which is more natural
and meaningful to the astronomer. Modify the unit of 'scale' so that
the same one, arcsec/pixel, is used across our pipeline.
Raise IOError if the SCAMP configuration file cannot be read
Rename variable 'marged_path' to 'merged_path'
Use **kwargs to pass keyword arguments — more compact, cleaner
Rename check_command() to which()

The current implementation of check_command() does not return the path
of the found executables, but just whether (i.e., True or False) they
are in the current environment. This is not only platform-dependent
(as it calls Unix's 'which' using the subprocess module), but also
makes it impossible to determine the path to the executables: we can
know that they are in the current environment, but not exactly were.

Make the function platform-independent by searching the PATH variable
for the name of the executable and checking whether it exists anywhere
within, returning a list of the full paths to the found executables.
This almost exactly replicates the functionality of Unix's 'which', so
also rename the function to which(). Note that the function can still
be used in the same way as before, as empty lists evaluate to False.

The code has been largely ripped from Twister's repository:
https://twistedmatrix.com/trac/browser/trunk/twisted/python/procutils.py
Mock os.environ to simulate that SExtractor is not installed

The idea of mocking methods.check_command() and make it always return
False in order to test that sextractor() raises SExtractorNotInstalled
when SExtractor cannot be found in the current environment is not the
way to go. It works, but depends on our knowledge that check_command()
is the function that sextractor() uses internally to check whether a
command is installed. This inhibits free refactoring and will cause
the unit test to fail the moment sextractor() no longer uses it.

A rather more appropriate approach to simulate that SExtractor is not
installed is to mock os.environ['PATH'] and set it to an empty string.
In this manner, as the environment variable is empty, all the commands
(and this includes SExtractor) appear as not installed on the system.
Define the names of the executables in module-level variables
Rename module-level variable HEADER_SUFFIX to SCAMP_HEADER_SUFFIX
Add support for multiple arguments to which()

Allow the function to take multiple arguments, and for each one of
them find the path of the corresponding executables in the current
environment. The returned list contains the paths in the order in
which they were found.

Note that, unlike Unix's 'which' (whose exit status is zero when all
the specified commands are found and executable, and one when one or
more of them is not), this function always succeeds: it returns an
empty list when none of the commands are found, but other than that
there is no way of knowing, without examining the returned list,
whether a specific command was found.