Add Catalog.from_sequence class method

This class method returns a Catalog that contains the Star objects
passed as arguments. We will need to use it because, now that Catalog
uses tuple as its base class, neither item assignment nor deletion are
possible, so we cannot modify a SExtractor catalog after it is loaded
into memory. In case we need to discard some stars (e.g., those above
the saturation threshold) this method can be used to create another
Catalog with the non-discarded ones — note that we could use a list
comprehension, but that would give us a list, not a Catalog object.
Add unit test for Catalog.from_sequence
Use Catalog.from_sequence to filter out stars too close to the edges

Now that it subclasses tuple, it is no longer possible to iterate a
Catalog backwards removing those stars that are too close to the image
edges. Therefore, we first have to identify the stars that are not to
be ignored (i.e., those that are not too close to a border) and pass
them to Catalog.from_sequence() to create a new Catalog object
containing only them.
Use new Pixel objects to apply the offset

A consequence of commit f8d902d97, the offset cannot be applied to the
x- and y-coordinates of each Pixel, as the class is now immutable — it
is necessary to create a new object with the updated values.
Add ignore_del_exceptions context manager

Due to the precarious circumstances under which __del__() methods are
invoked, uncaught exceptions that occur during their execution are
ignored, and a warning is printed to standard error instead. This
context manager makes it possible to prevent these (and only these)
warning messages from being sent to standard error without having to
modify the code that raises the uncaught exception.
Ignore occasional warning printed by PyRAF's qphot

Use the methods.ignore_del_exceptions context manager to suppress the
warning message that is, at times, sent to the standard error by
PyRAF's qphot. This happens when pyraf.subproc.Subprocess.__del__()
fails to kill the 'x_images.e' subprocess and consequently raises an
exception:

"Exception pyraf.subproc.SubprocessError: SubprocessError("Failed kill
of subproc 24600, '/iraf/iraf/bin.linux/x_images.e -c', with signals
['TERM', 'KILL']",) in <bound method Subprocess.__del__ of <Subprocess
'/iraf/iraf/bin.linux/x_images.e -c', at 7f9f3f408710>> ignored"

This exception, being raised in __del__(), is ignored, but we do not
want the warning to be printed either — it only serves to clutter the
output with ugly messages that are not of interest to the user.
Fix typographical error — 'its' instead of 'is'
Add high-level command 'lemon'

In the same way that Git differentiates between low-level ('plumbing')
commands, designed to be chained together Unix style, and high-level
('porcelain') ones, which are more user-friendly, LEMON will provide a
single point of entry to all of the functionality implemented by the
pipeline: the 'lemon' command (note the absence of '.py' extension).

The task to be performed will be specified by a subcommand (e.g.,
"lemon photometry"). The corresponding module (such as photometry.py)
will be then imported and its main() method called, with the rest of
arguments passed to it.

In case no arguments are provided, this first version of the 'lemon'
command shows a help message (also disturbingly similar to that of
Git) with all the available subcommands.
Add --help option

Display the show message not only if no arguments are passed, but also
when the --help option is used. Note that we are detecting this option
without optparse, as that approach would not work if other options
(for example, --pixels when doing photometry) were used — these are
recognized by the option parsers defined in each module (such as
photometry.py), but they are unknown to this hypothetical upper-level
parser, which would generate an error message along the lines of
"error: no such option: --pixels" and exit with error status 2.
Show error message and exit if subcommand is unrecognized

The name of the LEMON subcommand (task) to execute must exactly match,
case included, one of the following: import, seeing, offsets, mosaic,
astrometry, annuli, photometry, diffphot and periods. If that is not
the case, an error message is printed to the standard error and the
program exits with a code of 1. Note that the subcommands match the
name of the modules that implement the different pipeline stages.
Show suggestions, if any, when the subcommand does not exist

When the subcommand specified by the user is unrecognized, compare it
to the list of available tasks and compute the list of the best 'good
enough' matches using the difflib.get_close_matches function. These
are displayed as suggestions to the user — who might have, for
example, typed 'pohtometry' instead of 'photometry'.
Fix missing left parenthesis
Import the task module and execute its main() function

If the subcommand is a valid one, import the LEMON module of the same
name (e.g., photometry.py when the photometry subcommand is specified)
and run its main() function. Note that we need to use the __import__
built-in function, instead of the 'import' statement, as the name of
the module is only known at runtime.
Append the name of the subcommand to sys.argv[0]

Replace sys.argv[0] with the name of the program (lemon) followed by
the specified subcommand (for example, diffphot). Although sys.argv[0]
is not passed to the main() function of the imported module, that is
where optparse looks up the name of the script when the brief summary
of options is displayed (that is, when -h or --help are used).

In short: make the optpase message start with something like, for
example, "Usage: lemon diffphot [OPTION]... INPUT_DB", instead of
"Usage: lemon [OPTION]... INPUT_DB" — note how the subcommand is
included in the former case.
Remove execute permissions from LEMON modules

The modules of the pipeline with the different stages of the pipeline
do not need to be executable anymore: they are not invoked directly by
the user, but through 'lemon', which imports them as needed and calls
their main() method.
Remove unused imports
Add several improvements to the deprecation decorator

1) Use functools.wrap() to make the returned wrapper look like the
wrapped function by copying its metadata. Until now the metadata of
the returned function has reflected the wrapper definition, not the
decorated function.

2) Set stacklevel = 2 when DeprecationWarning is issued, so that the
warning appears as coming from the decorated (deprecated) function,
rather than from the decorator.

3) Emit the warning every time that the deprecated function is called,
not only the first time.
Fix comma not followed by a space
Raise IOError (string exceptions were deprecated in Python 2.5)
Use functools.wraps() in the memoization decorator