• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keflavich / image_registration / 123

pending completion
123

Pull #8

travis-ci

keflavich
more docstring fixes
Pull Request #8: Python 3.4 support

73 of 73 new or added lines in 17 files covered. (100.0%)

488 of 1400 relevant lines covered (34.86%)

0.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.36
/image_registration/FITS_tools/match_images.py
1
import numpy as np
1✔
2
from .. import chi2_shift,chi2_shift_iterzoom
1✔
3
try:
1✔
4
    import astropy.io.fits as pyfits
1✔
5
    import astropy.wcs as pywcs
1✔
6
except ImportError:
×
7
    import pyfits
×
8
    import pywcs
×
9
from .load_header import load_data,load_header
1✔
10
from ..fft_tools.shift import shift2d
1✔
11

12
def project_to_header(fitsfile, header, use_montage=True, quiet=True,
1✔
13
                      **kwargs):
14
    """
15
    Light wrapper of montage with hcongrid as a backup
16

17
    Parameters
18
    ----------
19
        fitsfile : string
20
            a FITS file name
21
        header : pyfits.Header
22
            A pyfits Header instance with valid WCS to project to
23
        use_montage : bool
24
            Use montage or hcongrid (scipy's map_coordinates)
25
        quiet : bool
26
            Silence Montage's output
27

28
    Returns
29
    -------
30
        np.ndarray image projected to header's coordinates
31

32
    """
33
    try:
×
34
        import montage
×
35
        montageOK=True
×
36
    except ImportError:
×
37
        montageOK=False
×
38
    try:
×
39
        from .hcongrid import hcongrid
×
40
        hcongridOK=True
×
41
    except ImportError:
×
42
        hcongridOK=False
×
43
    import tempfile
×
44

45
    if montageOK and use_montage:
×
46
        temp_headerfile = tempfile.NamedTemporaryFile()
×
47
        header.toTxtFile(temp_headerfile.name)
×
48

49
        if hasattr(fitsfile, 'writeto'):
×
50
            fitsobj = fitsfile
×
51
            fitsfileobj = tempfile.NamedTemporaryFile()
×
52
            fitsfile = fitsfileobj.name
×
53
            fitsobj.writeto(fitsfile)
×
54

55
        outfile = tempfile.NamedTemporaryFile()
×
56
        montage.wrappers.reproject(fitsfile,
×
57
                                   outfile.name,
58
                                   temp_headerfile.name,
59
                                   exact_size=True,
60
                                   silent_cleanup=quiet)
61
        image = pyfits.getdata(outfile.name)
×
62
        
63
        outfile.close()
×
64
        temp_headerfile.close()
×
65
        try:
×
66
            fitsfileobj.close()
×
67
        except NameError:
×
68
            pass
×
69
    elif hcongridOK:
×
70
        image = hcongrid(load_data(fitsfile),
×
71
                         load_header(fitsfile),
72
                         header)
73

74
    return image
×
75

76
def match_fits(fitsfile1, fitsfile2, header=None, sigma_cut=False,
1✔
77
               return_header=False, use_montage=False, **kwargs):
78
    """
79
    Project one FITS file into another's coordinates
80
    If sigma_cut is used, will try to find only regions that are significant
81
    in both images using the standard deviation
82

83
    Parameters
84
    ----------
85
    fitsfile1: str
86
        Reference fits file name
87
    fitsfile2: str
88
        Offset fits file name
89
    header: pyfits.Header
90
        Optional - can pass a header to projet both images to
91
    sigma_cut: bool or int
92
        Perform a sigma-cut on the returned images at this level
93
    use_montage: bool
94
        Use montage for the reprojection into the same pixel space?  Otherwise,
95
        use scipy.
96

97
    Returns
98
    -------
99
    image1,image2,[header] : 
100
        Two images projected into the same space, and optionally
101
        the header used to project them
102
    """
103

×
104
    if header is None:
×
105
        header = load_header(fitsfile1)
×
106
        image1 = load_data(fitsfile1)
107
    else: # project image 1 to input header coordinates
×
108
        image1 = project_to_header(fitsfile1, header, use_montage=use_montage)
109

110
    # project image 2 to image 1 coordinates
×
111
    image2_projected = project_to_header(fitsfile2, header, use_montage=use_montage)
112

×
113
    if image1.shape != image2_projected.shape:
×
114
        raise ValueError("Failed to reproject images to same shape.")
115

×
116
    if sigma_cut:
×
117
        corr_image1 = image1*(image1 > image1.std()*sigma_cut)
×
118
        corr_image2 = image2_projected*(image2_projected > image2_projected.std()*sigma_cut)
×
119
        OK = (corr_image1==corr_image1)*(corr_image2==corr_image2) 
×
120
        if (corr_image1[OK]*corr_image2[OK]).sum() == 0:
×
121
            print("Could not use sigma_cut of %f because it excluded all valid data" % sigma_cut)
×
122
            corr_image1 = image1
×
123
            corr_image2 = image2_projected
124
    else:
×
125
        corr_image1 = image1
×
126
        corr_image2 = image2_projected
127

×
128
    returns = corr_image1, corr_image2
×
129
    if return_header:
×
130
        returns = returns + (header,)
×
131
    return returns
132

1✔
133
def register_fits(fitsfile1, fitsfile2, errfile=None, return_error=True,
134
                  register_method=chi2_shift_iterzoom,
135
                  return_cropped_images=False, return_shifted_image=False,
136
                  return_header=False, use_montage=False, **kwargs):
137
    """
138
    Determine the shift between two FITS images using the cross-correlation
139
    technique.  Requires montage or hcongrid.
140

141
    kwargs are passed to :func:`register_method`
142

143
    Parameters
144
    ----------
145
    fitsfile1: str
146
        Reference fits file name
147
    fitsfile2: str
148
        Offset fits file name
149
    errfile : str [optional]
150
        An error image, intended to correspond to fitsfile2
151
    register_method : function
152
        Can be any of the shift functions in :mod:`image_registration`.
153
        Defaults to :func:`chi2_shift`
154
    return_errors: bool
155
        Return the errors on each parameter in addition to the fitted offset
156
    return_cropped_images: bool
157
        Returns the images used for the analysis in addition to the measured
158
        offsets
159
    return_shifted_images: bool
160
        Return image 2 shifted into image 1's space
161
    return_header : bool
162
        Return the header the images have been projected to
163
    quiet: bool
164
        Silence messages?
165
    sigma_cut: bool or int
166
        Perform a sigma-cut before cross-correlating the images to minimize
167
        noise correlation?
168
    use_montage: bool
169
        Use montage for the reprojection into the same pixel space?  Otherwise,
170
        use scipy.
171

172
    Returns
173
    -------
174
    xoff,yoff : (float,float)
175
        pixel offsets
176
    xoff_wcs,yoff_wcs : (float,float)
177
        world coordinate offsets
178
    exoff,eyoff : (float,float) (only if `return_errors` is True)
179
        Standard error on the fitted pixel offsets
180
    exoff_wcs,eyoff_wcs : (float,float) (only if `return_errors` is True)
181
        Standard error on the fitted world coordinate offsets
182
    proj_image1, proj_image2 : (ndarray,ndarray) (only if `return_cropped_images` is True)
183
        The images projected into the same coordinates
184
    shifted_image2 : ndarray (if `return_shifted_image` is True)
185
        The second image projected *and shifted* to match image 1.
186
    header : :class:`pyfits.Header` (only if `return_header` is True)
187
        The header the images have been projected to
188

189
    """
×
190
    proj_image1, proj_image2, header = match_fits(fitsfile1, fitsfile2,
191
            return_header=True, **kwargs)
192

×
193
    if errfile is not None:
×
194
        errimage = project_to_header(errfile, header, use_montage=use_montage, **kwargs)
195
    else:
×
196
        errimage = None
197

×
198
    xoff,yoff,exoff,eyoff = register_method(proj_image1, proj_image2,
199
            err=errimage, return_error=True, **kwargs)
200
    
201
    wcs = pywcs.WCS(header)
×
202
    try:
×
203
        cdelt = wcs.wcs.cd.diagonal()
×
204
    except AttributeError:
×
205
        cdelt = wcs.wcs.cdelt
×
206
    xoff_wcs,yoff_wcs = np.array([xoff,yoff])*cdelt
×
207
    exoff_wcs,eyoff_wcs = np.array([exoff,eyoff])*cdelt
×
208
    #try:
209
    #    xoff_wcs,yoff_wcs = np.inner( np.array([[xoff,0],[0,yoff]]), wcs.wcs.cd )[[0,1],[0,1]]
210
    #except AttributeError:
211
    #    xoff_wcs,yoff_wcs = 0,0
212

213
    returns = xoff,yoff,xoff_wcs,yoff_wcs
×
214
    if return_error:
×
215
        returns = returns + (exoff,eyoff,exoff_wcs,eyoff_wcs)
×
216
    if return_cropped_images:
×
217
        returns = returns + (proj_image1,proj_image2)
×
218
    if return_shifted_image:
×
219
        shifted_im2 = shift2d(proj_image2, -xoff, -yoff)
×
220
        returns = returns + (shifted_im2,)
×
221
    if return_header:
×
222
        returns = returns + (header,)
×
223
    return returns
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2024 Coveralls, Inc