/usr/lib/python3/dist-packages/photutils/isophote/harmonics.py is in python3-photutils 0.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | # Licensed under a 3-clause BSD style license - see LICENSE.rst
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import numpy as np
__all__ = ['first_and_second_harmonic_function',
'fit_first_and_second_harmonics', 'fit_upper_harmonic']
def _least_squares_fit(optimize_func, parameters):
# call the least squares fitting
# function and handle the result.
from scipy.optimize import leastsq
solution = leastsq(optimize_func, parameters, full_output=True)
if solution[4] > 4:
raise RuntimeError("Error in least squares fit: " + solution[3])
# return coefficients and covariance matrix
return (solution[0], solution[1])
def first_and_second_harmonic_function(phi, c):
"""
Compute the harmonic function value used to calculate the
corrections for ellipse fitting.
This function includes simultaneously both the first and second
order harmonics:
.. math::
f(phi) = c[0] + c[1]*\\sin(phi) + c[2]*\\cos(phi) +
c[3]*\\sin(2*phi) + c[4]*\\cos(2*phi)
Parameters
----------
phi : float or `~numpy.ndarray`
The angle(s) along the elliptical path, going towards the positive
y axis, starting coincident with the position angle. That is, the
angles are defined from the semimajor axis that lies in
the positive x quadrant.
c : `~numpy.ndarray` of shape (5,)
Array containing the five harmonic coefficients.
Returns
-------
result : float or `~numpy.ndarray`
The function value(s) at the given input angle(s).
"""
return (c[0] + c[1]*np.sin(phi) + c[2]*np.cos(phi) + c[3]*np.sin(2*phi) +
c[4]*np.cos(2*phi))
def fit_first_and_second_harmonics(phi, intensities):
"""
Fit the first and second harmonic function values to a set of
(angle, intensity) pairs.
This function is used to compute corrections for ellipse fitting:
.. math::
f(phi) = y0 + a1*\\sin(phi) + b1*\\cos(phi) + a2*\\sin(2*phi) +
b2*\\cos(2*phi)
Parameters
----------
phi : float or `~numpy.ndarray`
The angle(s) along the elliptical path, going towards the positive
y axis, starting coincident with the position angle. That is, the
angles are defined from the semimajor axis that lies in
the positive x quadrant.
intensities : `~numpy.ndarray`
The intensities measured along the elliptical path, at the
angles defined by the ``phi`` parameter.
Returns
-------
y0, a1, b1, a2, b2 : float
The fitted harmonic coefficent values.
"""
a1 = b1 = a2 = b2 = 1.
def optimize_func(x):
return first_and_second_harmonic_function(
phi, np.array([x[0], x[1], x[2], x[3], x[4]])) - intensities
return _least_squares_fit(optimize_func, [np.mean(intensities), a1, b1,
a2, b2])
def fit_upper_harmonic(phi, intensities, order):
"""
Fit upper harmonic function to a set of (angle, intensity) pairs.
With ``order`` set to 3 or 4, the resulting amplitudes, divided by
the semimajor axis length and local gradient, measure the deviations
from perfect ellipticity.
The harmonic function that is fit is:
.. math::
y(phi, order) = y0 + An*\\sin(order*phi) + Bn*\\cos(order*phi)
Parameters
----------
phi : float or `~numpy.ndarray`
The angle(s) along the elliptical path, going towards the positive
y axis, starting coincident with the position angle. That is, the
angles are defined from the semimajor axis that lies in
the positive x quadrant.
intensities : `~numpy.ndarray`
The intensities measured along the elliptical path, at the
angles defined by the ``phi`` parameter.
order : int
The order of the harmonic to be fitted.
Returns
-------
y0, An, Bn : float
The fitted harmonic values.
"""
an = bn = 1.
def optimize_func(x):
return (x[0] + x[1]*np.sin(order*phi) + x[2]*np.cos(order*phi) -
intensities)
return _least_squares_fit(optimize_func, [np.mean(intensities), an, bn])
|