Skip to content

Commit

Permalink
Merge pull request #762 from mwcraig/combine-Combiner-docs-tests
Browse files Browse the repository at this point in the history
Document use of `ImageFileCollection` with `Combiner`/`combine`
  • Loading branch information
mwcraig committed Mar 11, 2021
2 parents 46ccaed + 4deb4b0 commit 7c7fe71
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 6 deletions.
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
New Features
^^^^^^^^^^^^

- Improve integration of ``ImageFileCollection`` with image combination
and document that integration [#762]

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Add memory_profiler as a test requirement [#739]
Expand All @@ -14,7 +17,7 @@ Bug Fixes
^^^^^^^^^

- ``test_image_collection.py`` in the test suite no longer produces
permanent files on disk and cleans up after itself. [#738]
permanent files on disk and cleans up after itself. [#738]

- Change ``Combiner`` to allow accepting either a list or a generator [#757]

Expand Down
8 changes: 6 additions & 2 deletions ccdproc/combiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,12 @@ def combine(img_list, output_file=None,
elif isinstance(img_list, str) and (',' in img_list):
img_list = img_list.split(',')
else:
raise ValueError(
"unrecognised input for list of images to combine.")
try:
# Maybe the input can be made into a list, so try that
img_list = list(img_list)
except TypeError:
raise ValueError(
"unrecognised input for list of images to combine.")

# Select Combine function to call in Combiner
if method == 'average':
Expand Down
38 changes: 38 additions & 0 deletions ccdproc/tests/test_combiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from astropy.nddata import CCDData

from ccdproc.combiner import Combiner, combine, _calculate_step_sizes
from ccdproc.image_collection import ImageFileCollection
from ccdproc.tests.pytest_fixtures import ccd_data as ccd_data_func


Expand Down Expand Up @@ -373,6 +374,43 @@ def test_combiner_result_dtype():
np.testing.assert_array_almost_equal(res.data, ref)


def test_combiner_image_file_collection_input(tmp_path):
# Regression check for #754
ccd = ccd_data_func()
for i in range(3):
ccd.write(tmp_path / f'ccd-{i}.fits')

ifc = ImageFileCollection(tmp_path)
comb = Combiner(ifc.ccds())
np.testing.assert_array_almost_equal(ccd.data,
comb.average_combine().data)


def test_combine_image_file_collection_input(tmp_path):
# Another regression check for #754 but this time with the
# combine function instead of Combiner
ccd = ccd_data_func()
for i in range(3):
ccd.write(tmp_path / f'ccd-{i}.fits')

ifc = ImageFileCollection(tmp_path)

comb_files = combine(ifc.files_filtered(include_path=True),
method='average')

comb_ccds = combine(ifc.ccds(), method='average')

np.testing.assert_array_almost_equal(ccd.data,
comb_files.data)
np.testing.assert_array_almost_equal(ccd.data,
comb_ccds.data)

with pytest.raises(FileNotFoundError):
# This should fail because the test is not running in the
# folder where the images are.
_ = combine(ifc.files_filtered())


# test combiner convenience function works with list of ccddata objects
def test_combine_average_ccddata():
fitsfile = get_pkg_data_filename('data/a8280271.fits')
Expand Down
52 changes: 49 additions & 3 deletions docs/image_combination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ Combining images and generating masks from clipping
===================================================

.. note::
No attempt has been made yet to optimize memory usage in
`~ccdproc.Combiner`. A copy is made, and a mask array
constructed, for each input image.
There are currently two interfaces to image combination. One is through
the `~ccdproc.Combiner` class, the other through the `~ccdproc.combine`
function. They offer *almost* identical capabilities. The primary
difference is that `~ccdproc.combine` allows you to place an upper
limit on the amount of memory used.

Work to improve the performance of image combination is ongoing.


The first step in combining a set of images is creating a
Expand Down Expand Up @@ -133,6 +137,48 @@ using `~ccdproc.Combiner.average_combine` or
`~ccdproc.Combiner.median_combine`).


.. _combination_with_IFC
Image combination using `~ccdproc.ImageFileCollection`
------------------------------------------------------

There are a couple of ways that image combination can be done if you are using
`~ccdproc.ImageFileCollection` to
:ref:`manage a folder of images <image_management>`.

For this example, a temporary folder with images in it is created:

>>> from tempfile import mkdtemp
>>> from pathlib import Path
>>> import numpy as np
>>> from astropy.nddata import CCDData
>>> from ccdproc import ImageFileCollection, Combiner, combine
>>>
>>> ccd = CCDData(np.ones([5, 5]), unit='adu')
>>>
>>> # Make a temporary folder as a path object
>>> image_folder = Path(mkdtemp())
>>> # Put several copies ccd in the temporary folder
>>> _ = [ccd.write(image_folder / f"ccd-{i}.fits") for i in range(3)]
>>> ifc = ImageFileCollection(image_folder)

To combine images using the `~ccdproc.Combiner` class you can use the ``ccds``
method of the `~ccdproc.ImageFileCollection`:

>>> c = Combiner(ifc.ccds())
>>> avg_combined = c.average_combine()

There two ways combine images using the `~ccdproc.combine` function. If the
images are large enough to combine in memory, then use the file names as the argument to `~ccdproc.combine`, like this:

>>> avg_combo_mem_lim = combine(ifc.files_filtered(include_path=True),
... mem_limit=1e9)

If memory use is not an issue, then the ``ccds`` method can be used here too:

>>> avg_combo = combine(ifc.ccds())



.. _reprojection:

Combination with image transformation and alignment
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ minversion = 2.2
testpaths = "ccdproc" "docs"
norecursedirs = build docs/_build
doctest_plus = enabled
addopts = --doctest-rst
markers =
data_size(N): set dimension of square data array for ccd_data fixture
data_scale(s): set the scale of the normal distribution used to generate data
Expand Down

0 comments on commit 7c7fe71

Please sign in to comment.