API Reference#
Autofocusers#
- class astrafocus.autofocuser.AnalyticResponseAutofocuser(autofocus_device_manager: AutofocusDeviceManager, exposure_time: float, focus_measure_operator: type[AnalyticResponseFocusedMeasureOperator], percent_to_cut: float = 50.0, focus_measure_operator_kwargs: dict | None = None, **kwargs)[source]#
Bases:
SweepingAutofocuserAutofocuser that fits a curve to the focus response curve and finds the best focus position.
- Parameters:
autofocus_device_manager (AutofocusDeviceManager) – Interface to control the telescope and its focuser.
exposure_time (float) – Exposure time for image acquisition.
focus_measure_operator (AnalyticResponseFocusedMeasureOperator) – Operator to measure the focus of images using an analytic response curve.
percent_to_cut (float, optional) – Percentage of worst-performing focus positions to exclude when updating the search range (default is 50.0).
**kwargs – Additional keyword arguments.
Examples
>>> from astrafocus.interface.simulation import CabaretDeviceSimulator >>> from astrafocus.star_size_focus_measure_operators import HFRStarFocusMeasure >>> from astrafocus.autofocuser import AnalyticResponseAutofocuser >>> sim = CabaretDeviceSimulator.default() >>> araf = AnalyticResponseAutofocuser( ... autofocus_device_manager=sim, ... exposure_time=1.0, ... focus_measure_operator=HFRStarFocusMeasure, ... n_steps=(20, 5), ... n_exposures=1, ... decrease_search_range=True, ... percent_to_cut=50, ... ) >>> _ = araf.run() >>> abs(araf.best_focus_position - 10000) < 500 True
- update_search_range(min_focus_pos, max_focus_pos) tuple[int, int][source]#
Update the search range for optimal focus position based on focus response curve.
Notes
This function updates the search range for the optimal focus position based on the focus response curve. It identifies the worst-performing positions in the current interval and adjusts the interval accordingly.
- class astrafocus.autofocuser.AutofocuserBase(autofocus_device_manager: AutofocusDeviceManager, focus_measure_operator: FocusMeasureOperator, exposure_time: float, search_range: tuple[int, int] | None = None, initial_position: int | None = None, keep_images: bool = False, secondary_focus_measure_operators: dict | None = None, search_range_is_relative: bool = False, save_path: str | None = None)[source]#
Bases:
ABCAbstract base class for autofocusing algorithms.
- Parameters:
autofocus_device_manager (AutofocusDeviceManager) – Interface to control the camera and its focuser.
focus_measure_operator (FocusMeasureOperator) – Operator to measure the focus of images.
exposure_time (float) – Exposure time for image acquisition.
search_range (Optional[Tuple[int, int]], optional) – Range of focus positions to search for the best focus (default is None, using the telescope’s allowed range).
initial_position (Optional[int], optional) – Initial focus position for the autofocus algorithm (default is None, using the telescope’s current position).
keep_images (bool, optional) – Whether to keep images for additional analysis (default is False).
secondary_focus_measure_operators (Optional[dict], optional) – Dictionary of additional focus measure operators for image analysis (default is an empty dictionary).
search_range_is_relative (bool, optional) – Whether the search range is relative to the initial position (default is False).
save_path (Optional[str], optional) – Path to save focus record to (default is None). If None, the focus record is not saved. If the path ends with ‘.csv’, the focus record is saved with that name. Otherwise, the focus record is saved as a csv file with a timestamp in the specified directory.
- focus_record#
DataFrame containing focus positions and corresponding focus measures.
- Type:
pd.DataFrame
- best_focus_position#
Best focus position determined by the autofocus algorithm.
- Type:
int or None
- _image_record#
List to store images if ‘keep_images’ is True.
- Type:
list
- measure_focus(image: np.ndarray) float:[source]#
Measure the focus of a given image using the specified focus measure operator.
- run():
Execute the autofocus algorithm. Handles exceptions and resets the focuser on failure.
- _run():
Abstract method to be implemented by subclasses for the actual autofocus algorithm.
- reset():
Reset the focuser to the initial position.
- get_focus_record() Tuple[np.ndarray, np.ndarray]:[source]#
Retrieve the focus record as sorted arrays of focus positions and corresponding measures.
Examples
>>> autofocus_instance = AutofocuserBase( ... autofocus_device_manager, focus_measure_operator, exposure_time ... ) >>> autofocus_instance.run()
- property focus_record#
- get_focus_record(threshold_nan_ratio: float = 0.25) tuple[ndarray, ndarray][source]#
Retrieve the focus record as sorted arrays of focus positions and corresponding measures.
- Parameters:
threshold_nan_ratio (float, optional) – Threshold for the ratio of NaN values in the focus record to issue a warning about data quality (default is 0.25). If the ratio of NaN values exceeds this threshold, a warning is logged indicating that the results may be unreliable.
- class astrafocus.autofocuser.NonParametricResponseAutofocuser(autofocus_device_manager, exposure_time, focus_measure_operator, extremum_estimator: RobustExtremumEstimator = <astrafocus.extremum_estimators.LOWESSExtremumEstimator object>, **kwargs)[source]#
Bases:
SweepingAutofocuser
- class astrafocus.autofocuser.SweepingAutofocuser(autofocus_device_manager: AutofocusDeviceManager, exposure_time: float, focus_measure_operator, n_steps: tuple[int] | int = (10,), n_exposures: int | ndarray = 1, search_range: tuple[int, int] | None = None, decrease_search_range=True, initial_position: int | None = None, **kwargs)[source]#
Bases:
AutofocuserBaseAutofocuser implementation using a sweeping algorithm.
- Parameters:
autofocus_device_manager (AutofocusDeviceManager) – Interface to control the camera and its focuser.
exposure_time (float) – Exposure time for image acquisition.
focus_measure_operator (FocusMeasureOperator) – Operator to measure the focus of images.
n_steps (Tuple[int], optional) – Number of steps for each sweep (default is (10,)). The length of this tuple determines the number of sweeps. The entries specify the number of steps for each sweep.
n_exposures (int | np.ndarray, optional) – Number of exposures at each focus position or an array specifying exposures for each sweep. If an integer is given, the same number of exposures is used for each sweep (default is 1). If an array is given, the length of the array must match the number of sweeps. (default is 1).
search_range (Optional[Tuple[int, int]], optional) – Range of focus positions to search for the best focus (default is None, using the telescope’s allowed range).
decrease_search_range (bool, optional) – Whether to decrease the search range after each sweep (default is True).
initial_position (Optional[int], optional) – Initial focus position for the autofocus algorithm (default is None, using the telescope’s current position).
**kwargs – Additional keyword arguments.
- n_sweeps#
Number of sweeps to perform.
- Type:
int
- n_steps#
Number of steps for each sweep.
- Type:
Tuple[int]
- n_exposures#
Number of exposures at each focus position.
- Type:
np.ndarray
- decrease_search_range#
Whether to decrease the search range after each sweep.
- Type:
bool
- _run():
Execute the sweeping autofocus algorithm.
- get_initial_direction(min_focus_pos, max_focus_pos) int:[source]#
Determine the initial direction of the sweep.
- find_best_focus_position():
Find and set the best focus position based on the recorded focus measures.
- _find_best_focus_position(focus_pos, focus_measure) Tuple[int, float]:[source]#
Abstract method to be implemented by subclasses for finding the best focus position.
- _run_sweep(search_positions, n_exposures):
Perform a single sweep across the specified focus positions.
- update_search_range(min_focus_pos, max_focus_pos) Tuple[int, int]:[source]#
Update the search range after each sweep.
- integer_linspace(min_focus_pos, max_focus_pos, n_steps) np.ndarray:[source]#
Generate integer-spaced values within the specified range.
Examples
>>> from astrafocus.interface.simulation import CabaretDeviceSimulator >>> from astrafocus.star_size_focus_measure_operators import HFRStarFocusMeasure >>> from astrafocus.autofocuser import AnalyticResponseAutofocuser >>> sim = CabaretDeviceSimulator.default() >>> saf = AnalyticResponseAutofocuser( ... autofocus_device_manager=sim, ... exposure_time=1.0, ... focus_measure_operator=HFRStarFocusMeasure, ... n_steps=(20, 5), ... n_exposures=1, ... decrease_search_range=True, ... percent_to_cut=50, ... ) >>> _ = saf.run() >>> len(saf.focus_record) > 0 True
- get_initial_direction(min_focus_pos, max_focus_pos)[source]#
Move upward if initial position is closer to min_focus_pos than max_focus_pos.
Focus measure operators#
Image-based operators#
- class astrafocus.focus_measure_operators.AbsoluteGradientFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Absolute Gradient'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.AnalyticResponseFocusedMeasureOperator(**kwargs)[source]#
Bases:
FocusMeasureOperator- name = 'Analytic Response Focused Measure Operator'#
- class astrafocus.focus_measure_operators.AutoCorrelationFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Auto Correlation'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.BrennerFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Brenner'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.FFTFocusMeasureTan2022(**kwargs)[source]#
Bases:
FocusMeasureOperatormathrm{FM} &= norm{bm{R phi}}_{1} \ mathrm{FFT}(x, y) &= R(x, y) expqty(-iphi(x,y)) \
- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'FFT Tan 2022'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.FFTPhaseMagnitudeProductFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperatormathrm{FM} &= norm{bm{R phi}}_{1} \ mathrm{FFT}(x, y) &= R(x, y) expqty(-iphi(x,y)) \
- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'FFT Phase Magnitude Product'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.FFTPowerFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperatormathrm{FM} &= norm{bm{R phi}}_{1} \ mathrm{FFT}(x, y) &= R(x, y) expqty(-iphi(x,y)) \
- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'FFT Power'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.FocusMeasureOperator(**kwargs)[source]#
Bases:
ABCAbstract base class for focus measure operators.
- smaller_is_better#
A class attribute indicating whether a smaller focus measure is considered better.
- Type:
bool
- name#
A class attribute representing the name of the focus measure operator.
- Type:
str
- __call__(image: np.ndarray, \*\*kwargs) float[source]#
Compute the focus measure of the input image.
- measure_focus(image: np.ndarray, \*\*kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- validate_image(image: np.ndarray)[source]#
Validate the input image for compatibility with focus measure algorithms.
- static convert_to_grayscale(image: ndarray[tuple[Any, ...], dtype[floating | integer]]) ndarray[tuple[Any, ...], dtype[floating | integer]][source]#
Convert the input image to grayscale.
- abstractmethod measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- smaller_is_better = True#
- class astrafocus.focus_measure_operators.LaplacianFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Laplacian'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.NormalizedVarianceFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Normalized Variance'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.SquaredGradientFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Squared Gradient'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.TenengradFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], ksize=1, **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Tenengrad'#
- smaller_is_better = False#
- class astrafocus.focus_measure_operators.VarianceOfLaplacianFocusMeasure(**kwargs)[source]#
Bases:
FocusMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Variance Of Laplacian'#
- smaller_is_better = False#
Star-size operators#
- class astrafocus.star_size_focus_measure_operators.GaussianStarFocusMeasure(ref_image=None, fwhm=2.0, star_find_threshold=5.0, absolute_detection_limit=0.0, cutout_size: int = 15, saturation_threshold=None, max_stars=100, **kwargs)[source]#
Bases:
StarSizeFocusMeasurefrom astrafocus.utils.fits import load_fits_with_focus_pos_from_directory fits_directory = “path_to_fits_files” image_data, headers, focus_pos = load_fits_with_focus_pos_from_directory(fits_directory)
image = image_data[0] gsfm = GaussianStarFocusMeasure(image, fwhm=2.0, star_find_threshold=8.0) gsfm.star_finder.selected_stars
import matplotlib.pyplot as plt fm_vals = [gsfm.measure_focus(image) for image in image_data] plt.plot(focus_pos, fm_vals, ls=’’, marker=’.’); plt.show() # doctest: +SKIP
plot_focus_response_curve(gsfm, image_data, focus_pos, plot_name=’gaussian_star.pdf’)
- static hyperbola(x, a=1, b=1, x_0=0, y_0=0)[source]#
Notes
If we want the hyperbola to be north-south opening, we need to use the parametrisation (y-y_0)**2/b**2 - (x-x_0)**2/a**2 = 1
Resulting in the following parametrisation of the north opening hyperbola y = b * sqrt(1 + ((x-x_0)/a)**2) + y_0
Examples
>>> x = np.linspace(-1, 2) >>> plt.plot(x, hyperbola(x=x, a=1, b=1, x_0=0, y_0=-1)); plt.show()
- name = 'Gaussian'#
- class astrafocus.star_size_focus_measure_operators.HFRStarFocusMeasure(ref_image=None, fwhm=2.0, star_find_threshold=5.0, absolute_detection_limit=0.0, cutout_size: int = 15, saturation_threshold=None, max_stars=100, **kwargs)[source]#
Bases:
StarSizeFocusMeasurefrom astrafocus.utils.fits import load_fits_with_focus_pos_from_directory fits_directory = “path_to_fits_files” image_data, headers, focus_pos = load_fits_with_focus_pos_from_directory(fits_directory)
image = image_data[0] hfrfm = HFRStarFocusMeasure(image, fwhm=2.0, star_find_threshold=8.0) hfrfm.star_finder.selected_stars
import matplotlib.pyplot as plt fm_vals = [hfrfm.measure_focus(image) for image in image_data] plt.plot(focus_pos, fm_vals/np.min(fm_vals), ls=’’, marker=’.’) plt.plot(
focus_pos, hfrfm.linear_V_curve(focus_pos, *(-0.003, 0.003, np.mean(focus_pos), np.min(fm_vals/np.min(fm_vals))))
) plt.show() # doctest: +SKIP
plot_focus_response_curve(hfrfm, image_data, focus_pos, plot_name=’HFR_star.pdf’)
hfrfm.fit_focus_response_curve(focus_pos, fm_vals/np.min(fm_vals)) hfrfm.get_focus_response_curve_fit(focus_pos) focus_pos_fine = np.linspace(np.min(focus_pos), np.max(focus_pos))
- static linear_V_curve(x, slope_left=-1, slope_right=1, x_centre=0, intercept=0)[source]#
Examples
>>> x = np.linspace(-2, 2, 200) >>> plt.plot(x, linear_V_curve(x=x)); plt.show()
y_min = slope_left*v_centre + intercept_left = slope_right*v_centre + intercept_right (slope_left-slope_right)*v_centre = intercept_right - intercept_left v_centre = (intercept_right-intercept_left)/(slope_left - slope_right)
intercept_diff = (intercept_right - intercept_left)
v_centre = intercept_diff /(slope_left - slope_right)
slope_left*(x-v_centre) + b = slope_left*x + (b - slope_left**v_centre) slope_right*(x-v_centre) + b = slope_right*x + (b - v_centre*slope_right) intercept_diff = v_centre*(slope_left-slope_right)
v_centre = (intercept_right - intercept_left) / (slope_left - slope_right)
- static linear_V_curve_prime(x, slope_left=-1, slope_right=1, intercept_left=0, intercept_right=0)[source]#
Examples
>>> x = np.linspace(-2, 2, 200) >>> plt.plot(x, linear_V_curve(x=x)); plt.show()
slope_left*v_centre + intercept_left = slope_right*v_centre + intercept_right (slope_left-slope_right)*v_centre = intercept_right - intercept_left v_centre = (intercept_right-intercept_left)/(slope_left - slope_right)
- name = 'HFR'#
- class astrafocus.star_size_focus_measure_operators.StarSizeFocusMeasure(model, ref_image=None, fwhm=2.0, star_find_threshold=5.0, absolute_detection_limit=0.0, cutout_size: int = 15, saturation_threshold=None, max_stars=100, **kwargs)[source]#
Bases:
AnalyticResponseFocusedMeasureOperator- measure_focus(image: ndarray[tuple[Any, ...], dtype[floating | integer]], cutout_size: int | None = None, **kwargs) float[source]#
Abstract method to be implemented by subclasses. Compute the focus measure of the input image.
- Parameters:
image (np.ndarray) – Input image.
- Returns:
Computed focus measure.
- Return type:
float
- name = 'Size'#
Extremum estimators#
Robust Extremum Estimation Module
This module provides a framework for robustly estimating the minimum or maximum values in a set of measurements using various techniques. It includes a base class and several subclasses, each implementing a different extremum estimation technique.
Classes#
RobustExtremumEstimator: Abstract base class providing methods for estimating extrema.
MedianFilterExtremumEstimation: Estimation using a median filter for robustness.
LOWESSExtremumEstimator: Estimation using Locally Weighted Scatterplot Smoothing (LOWESS).
SplineExtremumEstimator: Estimation using Univariate Spline interpolation.
RBFExtremumEstimator: Estimation using Radial Basis Function (RBF) interpolation.
- - `argmin(x, y, return_value=True)`: Returns the x-value corresponding to the minimum estimated y-value.
If return_value is True, also returns the estimated y-value at the minimum.
- - `argmax(x, y, return_value=True)`: Returns the x-value corresponding to the maximum estimated y-value.
If return_value is True, also returns the estimated y-value at the maximum.
- - `estimate_robust_signal(x, y)`: Abstract method to be implemented by subclasses for specific
extremum estimation techniques. Returns the x and y values of a smoothed version of the curve.
- class astrafocus.extremum_estimators.ExtremumEstimatorRegistry[source]#
Bases:
objectDictionary mapping string keys to extremum estimator classes.
Examples
>>> from astrafocus.extremum_estimators import ExtremumEstimatorRegistry >>> ExtremumEstimatorRegistry.list() ['lowess', 'median', 'rbf', 'spline'] >>> ExtremumEstimatorRegistry.from_name("spline") <class 'astrafocus.extremum_estimators.SplineExtremumEstimator'>
- classmethod from_name(key: str)[source]#
Get an ExtremumEstimator by fuzzy matching the key. Returns lowess if not found.
- class astrafocus.extremum_estimators.LOWESSExtremumEstimator(frac=0.5, it=3, **kwargs)[source]#
Bases:
RobustExtremumEstimator- estimate_robust_signal(x, y)[source]#
Estimates the robust signal using Locally Weighted Scatterplot Smoothing (LOWESS).
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
- Returns:
Tuple of x and y values of the smoothed curve.
- Return type:
Tuple[np.ndarray, np.ndarray]
- name = 'LOWESS'#
- class astrafocus.extremum_estimators.MedianFilterExtremumEstimation(size=10, **kwargs)[source]#
Bases:
RobustExtremumEstimator- estimate_robust_signal(x, y)[source]#
Estimates the robust signal using a median filter.
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
- Returns:
Tuple of x and y values of the smoothed curve.
- Return type:
Tuple[np.ndarray, np.ndarray]
- name = 'Median Filter Extremum Estimation'#
- class astrafocus.extremum_estimators.RBFExtremumEstimator(kernel='linear', smoothing=20, **kwargs)[source]#
Bases:
RobustExtremumEstimator- estimate_robust_signal(x, y)[source]#
Estimates the robust signal using Radial Basis Function (RBF) interpolation.
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
- Returns:
Tuple of x and y values of the smoothed curve.
- Return type:
Tuple[np.ndarray, np.ndarray]
- name = 'RBF'#
- class astrafocus.extremum_estimators.RobustExtremumEstimator[source]#
Bases:
ABC- argmax(x: ndarray, y: ndarray, return_value=True) float | tuple[float, float][source]#
Returns the x-value corresponding to the maximum estimated noise-resistant y-value.
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
return_value (bool) – Whether to return the estimated y-value at the maximum. Defaults to True.
- Returns:
The x-value corresponding to the maximum estimated noise-resistant y-value. If return_value is True, also returns the estimated y-value at the maximum.
- Return type:
float | Tuple[float, float]
- argmin(x: ndarray, y: ndarray, return_value=True) float | tuple[float, float][source]#
Returns the x-value corresponding to the minimum estimated noise-resistant y-value.
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
return_value (bool) – Whether to return the estimated y-value at the minimum. Defaults to True.
- Returns:
The x-value corresponding to the minimum estimated noise-resistant y-value. If return_value is True, also returns the estimated y-value at the minimum.
- Return type:
float | Tuple[float, float]
- abstractmethod estimate_robust_signal(x: ndarray, y: ndarray) tuple[ndarray, ndarray][source]#
Abstract method to be implemented by subclasses for robust extremum signal estimation.
- registry = {}#
Abstract base class for robust extremum estimation.
This class provides methods to estimate the minimum or maximum values in a set of measurements using various techniques. Subclasses must implement the estimate_robust_signal method.
- name#
The name of the extremum estimator, derived from the class name if not explicitly set.
- Type:
str
Examples
>>> from astrafocus.extremum_estimators import MedianFilterExtremumEstimation >>> estimator = MedianFilterExtremumEstimation(size=2) >>> y = np.array([10, 11, 8, 5, 4, 6, 9, 11, 11]) >>> x = np.arange(len(y)) >>> x_min, y_min = estimator.argmin(x, y) >>> print(f"{x_min}, {y_min}") 4, 5
- class astrafocus.extremum_estimators.SplineExtremumEstimator(k=2, **kwargs)[source]#
Bases:
RobustExtremumEstimator- estimate_robust_signal(x, y)[source]#
Estimates the robust signal using Univariate Spline interpolation.
- Parameters:
x (np.ndarray) – The input x values.
y (np.ndarray) – The input y values.
- Returns:
Tuple of x and y values of the smoothed curve.
- Return type:
Tuple[np.ndarray, np.ndarray]
- name = 'Spline'#
Star detection#
- class astrafocus.star_finder.StarFinder(ref_image: ndarray[tuple[Any, ...], dtype[floating | integer]], fwhm: float = 3.0, star_find_threshold: float = 4.0, absolute_detection_limit: float = 0.0, saturation_threshold: float | None = None, max_stars: int = 50)[source]#
Bases:
objectExamples
TargetFinder(ref_image)
- FALLBACK_THRESHOLDS = array([4. , 3. , 2.5])#
- classmethod find_sources(ref_image: ndarray[tuple[Any, ...], dtype[floating | integer]], fwhm: float = 3.0, threshold: float = 4.0, std=None, background=None, saturation_threshold=None, absolute_detection_limit: float = 0.0, max_stars: int = 50)[source]#
Detect and locate stars using a tiered-threshold DAOFIND approach.
This method performs an initial search at the specified threshold. If no sources are found, it automatically falls back to searching at progressively lower thresholds defined in FALLBACK_THRESHOLDS. This is designed to maintain autofocus reliability even when stars are blurred (out-of-focus) or sky transparency drops.
- Parameters:
ref_image (2D array_like) – The background-subtracted or raw image array.
fwhm (float, optional) – Full-Width at Half-Maximum (pixels) of the Gaussian kernel. Standard ground-based telescopes typically use 2.5 to 4.0.
threshold (float, optional) – Initial detection threshold in units of background standard deviation (sigma). Default is 4.0.
std (float, optional) – Background noise standard deviation. If None, estimated via sigma-clipped statistics.
background (float, optional) – Median background level. If None, estimated via sigma-clipped statistics.
saturation_threshold (float, optional) – Maximum allowed pixel value. Peaks above this are rejected (useful for excluding saturated stars that bias centroids).
absolute_detection_limit (float, optional) – The hard floor for detection in ADU/counts. The effective threshold is max(absolute_limit, std * threshold).
max_stars (int, optional) – Capping limit for returned sources to optimize downstream processing speed. Sorted by brightness.
- Returns:
A table of detected sources with centroids and photometry, or None if no sources meet the criteria even after fallbacks.
- Return type:
astropy.table.QTable or None
Notes
The tiered approach prevents the “Noise Explosion” problem. Searching immediately at 2.0 sigma on a noisy CMOS sensor can result in thousands of false positives, slowing down the characterization phase significantly. By starting higher and falling back only when necessary, we balance speed with sensitivity.
- class astrafocus.star_fitter.StarFitter(model: _ModelMeta, scale_factor: int = 1, fitter: <module 'astropy.modeling.fitting' from '/home/runner/work/astrafocus/astrafocus/.venv/lib/python3.11/site-packages/astropy/modeling/fitting.py'> = <astropy.modeling.fitting.LevMarLSQFitter object>)[source]#
Bases:
objectA class for fitting astropy-like models to star data to calculate the size of stars.
- Parameters:
model (astropy.modeling.Model) – The astropy model to fit to the star data.
- model#
The astropy model used for fitting.
- Type:
astropy.modeling.Model
- result#
The result of the fitting process.
- Type:
astropy.modeling.Model
- fwhm#
The full-width at half-maximum (FWHM) of the fitted model.
- Type:
float
- calculate_avg_fwhm(result)#
Calculate the average FWHM from the fitted model parameters.
- Raises:
ValueError – If the object has not been fitted yet or if FWHM calculation is not supported for the model type.
Examples
>>> from astropy.modeling import models >>> from astrafocus.interface.simulation import CabaretDeviceSimulator >>> from astrafocus.star_size_focus_measure_operators import GaussianStarFocusMeasure >>> image = CabaretDeviceSimulator.generate_image() >>> gsfm = GaussianStarFocusMeasure(image) >>> star = gsfm.star_finder.selected_stars[0] >>> star_fitter = StarFitter(models.Gaussian2D) >>> _ = star_fitter.fit_source(image, star=star, cutout_size=15) >>> bool(star_fitter.star_size > 0) True
- fit(star_data, *args, **kwargs)[source]#
Fit the specified model to the window around the star provided in star_data.
- Parameters:
star_data (numpy.ndarray) – A small section of the full image containing the intensity profile of the star.
*args (additional arguments and keyword arguments) – Additional arguments to pass to the model constructor.
**kwargs (additional arguments and keyword arguments) – Additional arguments to pass to the model constructor.
- integrate_source(image, star, cutout_size=15, fitter=<astropy.modeling.fitting.LevMarLSQFitter object>, *args, **kwargs)[source]#
- property parameter_dict#
- property result#
- property star_size#
Calculate the full-width at half-maximum (FWHM) of the fitted model. In the case of a 2d Gaussian, return the average FWHM.
Registries#
- class astrafocus.AnalyticResponseAutofocuser(autofocus_device_manager: AutofocusDeviceManager, exposure_time: float, focus_measure_operator: type[AnalyticResponseFocusedMeasureOperator], percent_to_cut: float = 50.0, focus_measure_operator_kwargs: dict | None = None, **kwargs)[source]
Bases:
SweepingAutofocuserAutofocuser that fits a curve to the focus response curve and finds the best focus position.
- Parameters:
autofocus_device_manager (AutofocusDeviceManager) – Interface to control the telescope and its focuser.
exposure_time (float) – Exposure time for image acquisition.
focus_measure_operator (AnalyticResponseFocusedMeasureOperator) – Operator to measure the focus of images using an analytic response curve.
percent_to_cut (float, optional) – Percentage of worst-performing focus positions to exclude when updating the search range (default is 50.0).
**kwargs – Additional keyword arguments.
Examples
>>> from astrafocus.interface.simulation import CabaretDeviceSimulator >>> from astrafocus.star_size_focus_measure_operators import HFRStarFocusMeasure >>> from astrafocus.autofocuser import AnalyticResponseAutofocuser >>> sim = CabaretDeviceSimulator.default() >>> araf = AnalyticResponseAutofocuser( ... autofocus_device_manager=sim, ... exposure_time=1.0, ... focus_measure_operator=HFRStarFocusMeasure, ... n_steps=(20, 5), ... n_exposures=1, ... decrease_search_range=True, ... percent_to_cut=50, ... ) >>> _ = araf.run() >>> abs(araf.best_focus_position - 10000) < 500 True
- fit_focus_response_curve(focus_pos: ndarray, focus_measure: ndarray)[source]
- get_focus_response_curve_fit(focus_pos: int)[source]
- update_search_range(min_focus_pos, max_focus_pos) tuple[int, int][source]
Update the search range for optimal focus position based on focus response curve.
Notes
This function updates the search range for the optimal focus position based on the focus response curve. It identifies the worst-performing positions in the current interval and adjusts the interval accordingly.
- class astrafocus.ExtremumEstimatorRegistry[source]
Bases:
objectDictionary mapping string keys to extremum estimator classes.
Examples
>>> from astrafocus.extremum_estimators import ExtremumEstimatorRegistry >>> ExtremumEstimatorRegistry.list() ['lowess', 'median', 'rbf', 'spline'] >>> ExtremumEstimatorRegistry.from_name("spline") <class 'astrafocus.extremum_estimators.SplineExtremumEstimator'>
- classmethod from_name(key: str)[source]
Get an ExtremumEstimator by fuzzy matching the key. Returns lowess if not found.
- classmethod get(key: str, default=<class 'astrafocus.extremum_estimators.LOWESSExtremumEstimator'>)[source]
Get a focus measure operator class by fuzzy matching the key. Returns hfr if not found.
- classmethod list()[source]
List all available extremum estimators.
- class astrafocus.FocusMeasureOperatorRegistry[source]
Bases:
objectRegistry mapping string keys to focus measure operator classes.
Examples
>>> from astrafocus import FocusMeasureOperatorRegistry >>> FocusMeasureOperatorRegistry.list() ['hfr', ..., 'auto_correlation'] >>> FocusMeasureOperatorRegistry.from_name("fft") <class 'astrafocus.focus_measure_operators.FFTFocusMeasureTan2022'>
- classmethod from_name(key: str)[source]
Get a focus measure operator class by fuzzy matching the key. Returns hfr if not found.
- classmethod get(key: str, default=<class 'astrafocus.star_size_focus_measure_operators.HFRStarFocusMeasure'>)[source]
Get a focus measure operator class by fuzzy matching the key. Returns hfr if not found.
- classmethod list()[source]
List all available focus measure operators.
- class astrafocus.FocusMeasureScan(operators: list[FocusMeasureOperator])[source]
Bases:
objectRun one or more focus measure operators over a sequence of FITS images.
- Parameters:
operators (list[FocusMeasureOperator]) – One or more focus measure operator instances to apply to each image.
Examples
>>> from astrafocus import FocusMeasureOperatorRegistry >>> from astrafocus.focus_measure_scan import FocusMeasureScan >>> scan = FocusMeasureScan.from_names(["Brenner", "Tenengrad", "FFT"]) >>> scan = FocusMeasureScan.from_names(["FFT"]) >>> scan.operators.append(FocusMeasureOperatorRegistry.from_name("HFR")(fwhm=4.0))
- classmethod from_names(names: list[str]) FocusMeasureScan[source]
Construct a FocusMeasureScan from a list of operator name strings.
- Parameters:
names (list[str]) – Operator names as accepted by
FocusMeasureOperatorRegistry.from_name(e.g.["brenner", "tenengrad"]).
- plot_all(df, plot_kwargs={}, log_scale=False, axes=None)[source]
- run(directory: str | Path, pattern: str = '*.fits', header_fields: list[str] | None = ['DATE-OBS', 'FOCUSPOS']) DataFrame[source]
Compute focus measures for all FITS files in a directory.
- Parameters:
directory (str or Path) – Directory containing FITS files.
pattern (str) – Glob pattern used to find FITS files. Default is
"*.fits".header_fields (list[str], optional) – FITS header keywords to extract into the result DataFrame (e.g.
["FOCPOS"]).
- Returns:
One row per file. Columns:
file, any requestedheader_fields, and one column per operator named byoperator.name.- Return type:
pd.DataFrame
Examples
>>> import tempfile >>> import cabaret >>> from cabaret.sources import Sources >>> import numpy as np >>> from astrafocus.focus_measure_scan import FocusMeasureScan >>> sources = Sources.from_arrays( ... ra=np.array([10.684]), dec=np.array([41.269]), fluxes=np.array([1e5]) ... ) >>> with tempfile.TemporaryDirectory() as tmpdir: ... obs = cabaret.Observatory(focuser={"position": 10000, "best_position": 10000}) ... _ = obs.generate_fits_image( ... ra=10.684, dec=41.269, sources=sources, exp_time=10, seed=42, ... file_path=f"{tmpdir}/focus_10000.fits", ... user_header={"FOCUSPOS": 10000}, ... ) ... scan = FocusMeasureScan.from_names(["Brenner"]) ... df = scan.run(tmpdir, header_fields=["FOCUSPOS"]) ... list(df.columns) ['file', 'FOCUSPOS', 'Brenner']
- class astrafocus.NonParametricResponseAutofocuser(autofocus_device_manager, exposure_time, focus_measure_operator, extremum_estimator: RobustExtremumEstimator = <astrafocus.extremum_estimators.LOWESSExtremumEstimator object>, **kwargs)[source]
Bases:
SweepingAutofocuser
Hardware interface#
- class astrafocus.interface.AutofocusDeviceManager(camera: CameraInterface, focuser: FocuserInterface, telescope: TelescopeInterface | None = TelescopeInterface())[source]
Bases:
ABCAbstract base class representing a telescope interface.
- Parameters:
camera (CameraInterface) – The interface with the camera.
focuser (FocuserInterface) – The interface with the focuser.
telescope (TelescopeInterface) – The interface with the telescope, responsible for slewing to a position on the sky.
- perform_exposure_at(focus_position: int, texp: float) ImageType[source]
Take an observation at a specific focus position with a given exposure time.
- move_focuser_to_position(desired_position)[source]
Move the focuser to a desired position.
- check_conditions() bool[source]
Check if observation conditions are good enough to take exposures. Default is True. The implementation of this method is optional, although it is recommended to provide one. This function will be used to interrupt the autofocus process if the conditions get bad.
Examples
Create a trivial autofocus device manager.
>>> from astrafocus.interface.device_manager import AutofocusDeviceManager >>> from astrafocus.interface.camera import TrivialCamera >>> from astrafocus.interface.focuser import TrivialFocuser >>> from astrafocus.interface.telescope import TrivialTelescope >>> autofocus_device_manager = AutofocusDeviceManager( ... camera=TrivialCamera(), ... focuser=TrivialFocuser(current_position=0, allowed_range=(0, 1000)), ... telescope=TrivialTelescope(), ... )
- check_conditions() bool[source]
- move_focuser_to_position(desired_position: int)[source]
- perform_exposure_at(focus_position: int, texp: float) ndarray[tuple[Any, ...], dtype[floating | integer]][source]
Take an observation at a specific focus position with a given exposure time.
- Parameters:
focus_position (int) – Desired focus position.
texp (float) – Exposure time.
- Returns:
Resulting image.
- Return type:
ImageType
- class astrafocus.interface.CameraInterface[source]
Bases:
ABCAbstract base class representing a telescope camera interface.
- perform_exposure(texp)[source]
Take an observation with a specified exposure time.
- abstractmethod perform_exposure(texp: float) ndarray[tuple[Any, ...], dtype[floating | integer]][source]
Abstract method to take an observation with a specified exposure time.
- Parameters:
texp (float) – Exposure time.
- Returns:
Resulting image.
- Return type:
ImageType
- class astrafocus.interface.FocuserInterface(current_position, allowed_range: tuple[int, int])[source]
Bases:
ABCA class to manage the focus of a telescope.
- position
The current focuser position in steps.
- Type:
int
- allowed_range
The range of allowed focuser steps (min_step, max_step).
- Type:
tuple
- move_by_steps(steps_to_move)[source]
Move the focuser relative to the current position by n steps.
- is_within_range(desired_position: int)[source]
Check whether a desired focuser position is within the allowed range.
- Parameters:
desired_position (int) – The desired focuser position to check.
- Returns:
True if the desired position is within the allowed range, False otherwise.
- Return type:
bool
- move_by_steps(steps_to_move: int)[source]
Move the focuser relative to the current position by n steps.
- Parameters:
steps_to_move (int) – The number of steps to move relative to the current position.
- Raises:
ValueError – If moving relative exceeds the allowed range.
- abstractmethod move_focuser_to_position(new_position: int)[source]
- property position
- validate_allowed_range()[source]
Validate the allowed range provided during initialization.
- Raises:
ValueError – If the allowed range is not a tuple, list, or numpy array, or if any items in the range are not integers, or if the range does not consist of two integers.
- validate_desired_position(desired_position: int)[source]
- class astrafocus.interface.TelescopeInterface[source]
Bases:
ABCA calss to interface the pointing of the telescope to a specific coordinate in the equatorial coordinate system.
- point_to(coordinates)[source]
Point the telescope to a specific coordinate in the equatorial coordinate system.
- Parameters:
coordinates (~astropy.coordinates.SkyCoord) – The ICRS coordinates that should be in the centre of the CCD.
- abstractmethod set_telescope_position(coordinates: SkyCoord)[source]
Point the telescope to a specific coordinate in the equatorial coordinate system.
- Parameters:
coordinates (~astropy.coordinates.SkyCoord) – The ICRS coordinates that should be in the centre of the CCD.
- validate_arguments(coordinates: SkyCoord)[source]
- class astrafocus.interface.device_manager.AutofocusDeviceManager(camera: CameraInterface, focuser: FocuserInterface, telescope: TelescopeInterface | None = TelescopeInterface())[source]#
Bases:
ABCAbstract base class representing a telescope interface.
- Parameters:
camera (CameraInterface) – The interface with the camera.
focuser (FocuserInterface) – The interface with the focuser.
telescope (TelescopeInterface) – The interface with the telescope, responsible for slewing to a position on the sky.
- perform_exposure_at(focus_position: int, texp: float) ImageType[source]#
Take an observation at a specific focus position with a given exposure time.
- check_conditions() bool[source]#
Check if observation conditions are good enough to take exposures. Default is True. The implementation of this method is optional, although it is recommended to provide one. This function will be used to interrupt the autofocus process if the conditions get bad.
Examples
Create a trivial autofocus device manager.
>>> from astrafocus.interface.device_manager import AutofocusDeviceManager >>> from astrafocus.interface.camera import TrivialCamera >>> from astrafocus.interface.focuser import TrivialFocuser >>> from astrafocus.interface.telescope import TrivialTelescope >>> autofocus_device_manager = AutofocusDeviceManager( ... camera=TrivialCamera(), ... focuser=TrivialFocuser(current_position=0, allowed_range=(0, 1000)), ... telescope=TrivialTelescope(), ... )
- perform_exposure_at(focus_position: int, texp: float) ndarray[tuple[Any, ...], dtype[floating | integer]][source]#
Take an observation at a specific focus position with a given exposure time.
- Parameters:
focus_position (int) – Desired focus position.
texp (float) – Exposure time.
- Returns:
Resulting image.
- Return type:
ImageType
- class astrafocus.interface.device_manager.TrivialAutofocusDeviceManager(camera: CameraInterface = TrivialCamera(), focuser: FocuserInterface = FocuserInterface(current_position=0, allowed_range=(0, 1000)), telescope: TelescopeInterface = TelescopeInterface())[source]#
Bases:
AutofocusDeviceManagerA trivial telescope interface for testing purposes.
- class astrafocus.interface.camera.CameraInterface[source]#
Bases:
ABCAbstract base class representing a telescope camera interface.
- class astrafocus.interface.camera.TrivialCamera[source]#
Bases:
CameraInterfaceA trivial camera interface for testing purposes.
- class astrafocus.interface.focuser.FocuserInterface(current_position, allowed_range: tuple[int, int])[source]#
Bases:
ABCA class to manage the focus of a telescope.
- position#
The current focuser position in steps.
- Type:
int
- allowed_range#
The range of allowed focuser steps (min_step, max_step).
- Type:
tuple
- is_within_range(desired_position: int)[source]#
Check whether a desired focuser position is within the allowed range.
- Parameters:
desired_position (int) – The desired focuser position to check.
- Returns:
True if the desired position is within the allowed range, False otherwise.
- Return type:
bool
- move_by_steps(steps_to_move: int)[source]#
Move the focuser relative to the current position by n steps.
- Parameters:
steps_to_move (int) – The number of steps to move relative to the current position.
- Raises:
ValueError – If moving relative exceeds the allowed range.
- property position#
- class astrafocus.interface.focuser.TrivialFocuser(current_position, allowed_range=tuple[int, int])[source]#
Bases:
FocuserInterfaceTrivial implementation to set the telescope focuser for testing purposes.
- class astrafocus.interface.telescope.TelescopeInterface[source]#
Bases:
ABCA calss to interface the pointing of the telescope to a specific coordinate in the equatorial coordinate system.
- point_to(coordinates)[source]#
Point the telescope to a specific coordinate in the equatorial coordinate system.
- Parameters:
coordinates (~astropy.coordinates.SkyCoord) – The ICRS coordinates that should be in the centre of the CCD.
- class astrafocus.interface.telescope.TrivialTelescope[source]#
Bases:
TelescopeInterfaceTrivial implementation to set the telescope position for testing purposes.
- class astrafocus.interface.simulation.ObservationBasedDeviceSimulator(current_position: int | None = None, allowed_range: tuple[int, int] | None = None, sleep_flag: bool = False, seconds_per_step: float = 0.5, image_data: list | None = None, headers: list[ndarray[tuple[Any, ...], dtype[floating | integer]]] | None = None, focus_pos: ndarray | None = None, fits_path: str | None = None, save_path: str | None = None)[source]#
Bases:
AutofocusDeviceSimulator
Sky targeting#
- class astrafocus.targeting.ZenithNeighbourhoodQuery(db_path: str, zenith_neighbourhood: ZenithNeighbourhood, maximal_number_of_stars: int | None = 1000000)[source]
Bases:
objectClass for querying a database based on a zenith neighbourhood.
- Parameters:
db_path (str) – Path to the database.
zenith_neighbourhood (ZenithNeighbourhood) – Zenith neighbourhood object.
maximal_number_of_stars (int, optional) – Maximum number of stars to be considered in the query (default is 1 000 000). This parameter is needed to prevent excessive queries that could lead to memory issues or long processing times.
Examples
- zenith_neighbourhood_query = ZenithNeighbourhoodQuery(
db_path=”path_to/database.db”, zenith_neighbourhood=zenith_neighbourhood
)
- classmethod create_from_location_and_angle(db_path: str, observatory_location: EarthLocation, maximal_zenith_angle: float | int | Angle, maximal_number_of_stars: int | None = 1000000, observation_time: Time | None = None) ZenithNeighbourhoodQuery[source]
Create an instance of the ZenithNeighbourhoodQuery class with specified parameters.
This class method is an alternative constructor that creates a ZenithNeighbourhoodQuery instance based on the provided observatory location, maximal zenith angle, and optional observation time.
- Parameters:
db_path (str) – The path to the database.
observatory_location (EarthLocation) – Location of the observatory.
maximal_zenith_angle (float, int, or Angle) – Maximum zenith angle for the neighbourhood in degrees.
maximal_number_of_stars (int, optional) – Maximum number of stars to be considered in the query (default is 1 000 000).
observation_time (Optional[Time], optional) – Observation time specified using astropy’s Time. (default is None, resulting to now)
Example
>>> db_path = '/path/to/database' >>> observatory_location = EarthLocation(lat=30.0, lon=-70.0, height=1000.0) >>> maximal_zenith_angle = 15.0 >>> observation_time = Time('2023-12-01T12:00:00') >>> zenith_neighbourhood_query = ZenithNeighbourhoodQuery.create_from_location_and_angle( ... db_path, observatory_location, maximal_zenith_angle, observation_time ... )
- filter_df_by_zenith_angle(df) ZenithNeighbourhoodQueryResult[source]
Filter DataFrame based on zenith angle.
- Parameters:
df (pd.DataFrame) – DataFrame to be filtered.
- Returns:
Result of the filtered DataFrame.
- Return type:
- static find_airmass_threshold_crossover(airmass_threshold: float | None = 1.2, airmass_model: Callable = <function plane_parallel_atmosphere>)[source]
- classmethod from_telescope_specs(telescope_specs, observation_time=None, maximal_zenith_angle=None, db_path=None) ZenithNeighbourhoodQuery[source]
Create an instance of the ZenithNeighbourhoodQuery class from an instance of the TelescopeSpecs class.
- Parameters:
telescope_specs (TelescopeSpecs) – An instance of the TelescopeSpecs class.
db_path (str, optional) – The path to the database, by default None
Example
>>> telescope_specs = TelescopeSpecs.load_telescope_config( ... file_path=path_to_config_file ... ) >>> zenith_neighbourhood_query = ( ... ZenithNeighbourhoodQuery.from_telescope_specs(telescope_specs) ... )
- query_full(n_sub_div=20, zenith_angle_strict=True, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None) ZenithNeighbourhoodQueryResult[source]
Query the smallest rectangle that covers the whole patch.
- Parameters:
n_sub_div (int, optional) – Number of subdivisions for approximation (default is 20).
zenith_angle_strict (bool, optional) – If True, filter results based on zenith angle (default is True).
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to query (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to query (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to query (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to query (default is None).
- Returns:
Result of the query.
- Return type:
- query_shardwise(n_sub_div=20, zenith_angle_strict=True, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None) ZenithNeighbourhoodQueryResult[source]
Query the database shard-wise, only searching each shard as far as needed.
- Parameters:
n_sub_div (int, optional) – Number of subdivisions for approximation (default is 20).
zenith_angle_strict (bool, optional) – If True, filter results based on zenith angle (default is True).
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to query (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to query (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to query (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to query (default is None).
- Returns:
Result of the query.
- Return type:
- astrafocus.targeting.find_airmass_threshold_crossover(airmass_threshold: float | None = 1.2, airmass_model: Callable = <function plane_parallel_atmosphere>)[source]
Find the zenith angle cutoff based on an airmass model and a threshold value.
- Parameters:
airmass_threshold (float, optional) – The threshold value, above which the airmass is considered too high.
airmass_model (Callable) – A callable function that takes zenith angles and returns airmass values.
- Returns:
The zenith angle cutoff that corresponds to the airmass falling below the threshold.
- Return type:
float
Notes
This function assumes that airmass_model increases monotonically as a function of zenith angle.
Examples
>>> float(find_airmass_threshold_crossover( ... airmass_threshold=1.2, airmass_model=plane_parallel_atmosphere ... )) 0.5846852994181003
- class astrafocus.targeting.zenith_neighbourhood_query.ZenithNeighbourhoodQuery(db_path: str, zenith_neighbourhood: ZenithNeighbourhood, maximal_number_of_stars: int | None = 1000000)[source]#
Bases:
objectClass for querying a database based on a zenith neighbourhood.
- Parameters:
db_path (str) – Path to the database.
zenith_neighbourhood (ZenithNeighbourhood) – Zenith neighbourhood object.
maximal_number_of_stars (int, optional) – Maximum number of stars to be considered in the query (default is 1 000 000). This parameter is needed to prevent excessive queries that could lead to memory issues or long processing times.
Examples
- zenith_neighbourhood_query = ZenithNeighbourhoodQuery(
db_path=”path_to/database.db”, zenith_neighbourhood=zenith_neighbourhood
)
- classmethod create_from_location_and_angle(db_path: str, observatory_location: EarthLocation, maximal_zenith_angle: float | int | Angle, maximal_number_of_stars: int | None = 1000000, observation_time: Time | None = None) ZenithNeighbourhoodQuery[source]#
Create an instance of the ZenithNeighbourhoodQuery class with specified parameters.
This class method is an alternative constructor that creates a ZenithNeighbourhoodQuery instance based on the provided observatory location, maximal zenith angle, and optional observation time.
- Parameters:
db_path (str) – The path to the database.
observatory_location (EarthLocation) – Location of the observatory.
maximal_zenith_angle (float, int, or Angle) – Maximum zenith angle for the neighbourhood in degrees.
maximal_number_of_stars (int, optional) – Maximum number of stars to be considered in the query (default is 1 000 000).
observation_time (Optional[Time], optional) – Observation time specified using astropy’s Time. (default is None, resulting to now)
Example
>>> db_path = '/path/to/database' >>> observatory_location = EarthLocation(lat=30.0, lon=-70.0, height=1000.0) >>> maximal_zenith_angle = 15.0 >>> observation_time = Time('2023-12-01T12:00:00') >>> zenith_neighbourhood_query = ZenithNeighbourhoodQuery.create_from_location_and_angle( ... db_path, observatory_location, maximal_zenith_angle, observation_time ... )
- filter_df_by_zenith_angle(df) ZenithNeighbourhoodQueryResult[source]#
Filter DataFrame based on zenith angle.
- Parameters:
df (pd.DataFrame) – DataFrame to be filtered.
- Returns:
Result of the filtered DataFrame.
- Return type:
- static find_airmass_threshold_crossover(airmass_threshold: float | None = 1.2, airmass_model: Callable = <function plane_parallel_atmosphere>)[source]#
- classmethod from_telescope_specs(telescope_specs, observation_time=None, maximal_zenith_angle=None, db_path=None) ZenithNeighbourhoodQuery[source]#
Create an instance of the ZenithNeighbourhoodQuery class from an instance of the TelescopeSpecs class.
- Parameters:
telescope_specs (TelescopeSpecs) – An instance of the TelescopeSpecs class.
db_path (str, optional) – The path to the database, by default None
Example
>>> telescope_specs = TelescopeSpecs.load_telescope_config( ... file_path=path_to_config_file ... ) >>> zenith_neighbourhood_query = ( ... ZenithNeighbourhoodQuery.from_telescope_specs(telescope_specs) ... )
- query_full(n_sub_div=20, zenith_angle_strict=True, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None) ZenithNeighbourhoodQueryResult[source]#
Query the smallest rectangle that covers the whole patch.
- Parameters:
n_sub_div (int, optional) – Number of subdivisions for approximation (default is 20).
zenith_angle_strict (bool, optional) – If True, filter results based on zenith angle (default is True).
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to query (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to query (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to query (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to query (default is None).
- Returns:
Result of the query.
- Return type:
- query_shardwise(n_sub_div=20, zenith_angle_strict=True, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None) ZenithNeighbourhoodQueryResult[source]#
Query the database shard-wise, only searching each shard as far as needed.
- Parameters:
n_sub_div (int, optional) – Number of subdivisions for approximation (default is 20).
zenith_angle_strict (bool, optional) – If True, filter results based on zenith angle (default is True).
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to query (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to query (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to query (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to query (default is None).
- Returns:
Result of the query.
- Return type:
- class astrafocus.targeting.zenith_neighbourhood.ZenithNeighbourhood(observatory_location: EarthLocation, observation_time: Time | None = None, maximal_zenith_angle: Angle | float = <Angle 10. deg>)[source]#
Bases:
objectClass representing a zenith neighbourhood for astronomical observations.
- Parameters:
observatory_location (Optional[EarthLocation], optional) – Location of the observatory specified using astropy’s EarthLocation.
observation_time (Optional[Time], optional) – Observation time specified using astropy’s Time.
maximal_zenith_angle (float, optional) – Maximum zenith angle for the neighbourhood in degrees (default is DEFAULT_MAXIMAL_ZENITH_ANGLE).
Examples
# Zenith neighbourhood now >>> from astropy.coordinates import EarthLocation >>> import astropy.units as u >>> speculoos_geo_coords = { … “lat”: -24.627222 * u.deg, “lon”: -70.404167 * u.deg, “height”: 2635 * u.m … } >>> zn = ZenithNeighbourhood( … observatory_location=EarthLocation(**speculoos_geo_coords), … maximal_zenith_angle=10 * u.deg … )
# Zenith neighbourhood at a specific time, crossing the 0, 360 deg boundary >>> import astropy >>> from astrafocus.targeting.zenith_neighbourhood import ( … ZenithNeighbourhood, DEFAULT_MAXIMAL_ZENITH_ANGLE … ) >>> zenith_neighbourhood = ZenithNeighbourhood( … maximal_zenith_angle=DEFAULT_MAXIMAL_ZENITH_ANGLE, … observatory_location=EarthLocation(**speculoos_geo_coords), … observation_time=astropy.time.Time(“2023-11-23 00:35:54.5018”) … )
- classmethod from_telescope_specs(telescope_specs: TelescopeSpecs, observation_time=None, maximal_zenith_angle=None)[source]#
- get_constant_approximation(n_approx=3, n_sub_div=20, south=None, north=None)[source]#
Calculate constant approximation.
- get_constant_approximation_shards_deg(n_sub_div)[source]#
Calculate constant approximation in degrees.
- Parameters:
n_sub_div (int) – Number of subdivisions for approximation.
- Returns:
Constant declinations and corresponding RA bounds in degrees.
- Return type:
Tuple[np.ndarray, np.ndarray]
- get_ra_bounds(n: int, south: float | None = None, north: float | None = None) tuple[ndarray, ndarray][source]#
Calculate exact RA bounds between specified declinations.
- Parameters:
n (int) – Number of subdivisions.
south (Optional[float], optional) – Southern declination in radians (default is None).
north (Optional[float], optional) – Northern declination in radians (default is None).
- Returns:
Declinations and corresponding RA bounds.
- Return type:
Tuple[np.ndarray, np.ndarray]
- class astrafocus.targeting.zenith_neighbourhood_query_result.ZenithNeighbourhoodQueryResult(*args, **kwargs)[source]#
Bases:
DataFrameClass representing the result of a zenith neighbourhood query.
Examples
>>> from astrafocus.targeting.zenith_neighbourhood import ZenithNeighbourhood >>> from astrafocus.targeting.zenith_neighbourhood_query import ZenithNeighbourhoodQuery
>>> speculoos_geo_coords = { ... "lat": -24.627222 * u.deg, "lon": -70.404167 * u.deg, "height": 2635 * u.m ... } >>> zn = ZenithNeighbourhood( ... observatory_location=EarthLocation(**speculoos_geo_coords), ... maximal_zenith_angle=10 * u.deg, ... ) >>> zenith_neighbourhood_query = ZenithNeighbourhoodQuery( ... db_path="path_to/database.db", zenith_neighbourhood=zn ... ) >>> df = zenith_neighbourhood_query.query_shardwise(n_sub_div=20)
- add_zenith_angle_and_cartesian_coordinates(zenith_neighbourhood)[source]#
Add zenith angle and Cartesian coordinates to the DataFrame.
- Parameters:
zenith_neighbourhood (ZenithNeighbourhood) – Zenith neighbourhood object.
- determine_stars_in_neighbourhood(height=0.19444443333333333, width=0.19444444333333333)[source]#
Determine the number of stars in the neighbourhood of all stars in the DataFrame.
- determine_stars_in_neighbourhood_of_star(ind, height=0.19444443333333333, width=0.19444444333333333)[source]#
Determine the number of stars in the neighbourhood of a single stars.
- static find_bounds_star(phi_c, theta_c, height=0.19444443333333333, width=0.19444444333333333)[source]#
- find_stars_in_neighbourhood(ind, height=0.19444443333333333, width=0.19444444333333333)[source]#
Find all stars in the neighbourhood of a specific stars.
- mask_by_magnitude(g_mag_range=(6, 12), j_mag_range=(6, 12))[source]#
Mask the DataFrame based on magnitude ranges.
- Parameters:
g_mag_range (Tuple[float, float], optional) – Range for the G magnitude (default is G_MAG_RANGE).
j_mag_range (Tuple[float, float], optional) – Range for the J magnitude (default is J_MAG_RANGE).
- Returns:
Masked result based on magnitude ranges.
- Return type:
Astronomical Airmass Calculation Module
This module provides functions for calculating astronomical airmass and related parameters.
Functions#
- find_airmass_threshold_crossover(airmass_threshold=1.2, airmass_model)
Find the zenith angle cutoff based on an airmass model and a threshold value.
- zenith_angle(altitude)
Calculate the zenith angle from the given altitude.
- plane_parallel_atmosphere(zenith_angle)
Calculate airmass in a plane-parallel atmosphere.
- pickering_interpolative(zenith_angle)
Calculate airmass using the Pickering interpolative formula.
- rosenberg_interpolative(zenith_angle)
Calculate airmass using the Rosenberg interpolative formula.
Example Usage#
>>> from astrafocus.targeting import airmass_models
>>> cutoff = airmass_models.find_airmass_threshold_crossover(
... airmass_threshold=1.2, airmass_model=airmass_models.plane_parallel_atmosphere
... )
>>> zenith = airmass_models.zenith_angle(0.5)
>>> airmass_pickering = airmass_models.pickering_interpolative(zenith)
>>> airmass_rosenberg = airmass_models.rosenberg_interpolative(zenith)
Sources#
- astrafocus.targeting.airmass_models.find_airmass_threshold_crossover(airmass_threshold: float | None = 1.2, airmass_model: Callable = <function plane_parallel_atmosphere>)[source]#
Find the zenith angle cutoff based on an airmass model and a threshold value.
- Parameters:
airmass_threshold (float, optional) – The threshold value, above which the airmass is considered too high.
airmass_model (Callable) – A callable function that takes zenith angles and returns airmass values.
- Returns:
The zenith angle cutoff that corresponds to the airmass falling below the threshold.
- Return type:
float
Notes
This function assumes that airmass_model increases monotonically as a function of zenith angle.
Examples
>>> float(find_airmass_threshold_crossover( ... airmass_threshold=1.2, airmass_model=plane_parallel_atmosphere ... )) 0.5846852994181003
- astrafocus.targeting.airmass_models.pickering_interpolative(zenith_angle)[source]#
Calculate the airmass using the Pickering interpolative formula.
- Parameters:
zenith_angle (float) – Zenith angle in radians.
- Returns:
The airmass value calculated using the Pickering formula.
- Return type:
float
Examples
>>> float(pickering_interpolative(0)) 1.000000196171337
- astrafocus.targeting.airmass_models.plane_parallel_atmosphere(zenith_angle)[source]#
Calculate the airmass in a plane-parallel atmosphere model.
- Parameters:
zenith_angle (float) – Zenith angle in radians.
- Returns:
The airmass value for the given zenith angle.
- Return type:
float
Examples
>>> float(plane_parallel_atmosphere(0)) 1.0
- astrafocus.targeting.airmass_models.rosenberg_interpolative(zenith_angle)[source]#
Calculate the airmass using the Rosenberg interpolative formula.
- Parameters:
zenith_angle (float) – Zenith angle in radians.
- Returns:
The airmass value calculated using the Rosenberg formula.
- Return type:
float
Examples
>>> float(rosenberg_interpolative(0)) 0.9999995824576546
- astrafocus.targeting.airmass_models.zenith_angle(altitude)[source]#
Calculate the zenith angle from the given altitude.
- Parameters:
altitude (float) – Altitude angle in radians.
- Returns:
Zenith angle in radians.
- Return type:
float
Examples
>>> zenith_angle(0) * 180/np.pi 90.0
- class astrafocus.targeting.celestial_bounds_calculator.CelestialBoundsCalculatorInterface[source]#
Bases:
ABC- get_pole_dec_bounds(dec_bounds, pole_tolerance)[source]#
Create an SQLite-style query based on Declination bounds.
- class astrafocus.targeting.celestial_bounds_calculator.CelestialBoundsCalculatorWCS(wcs)[source]#
Bases:
CelestialBoundsCalculatorInterfacecbc = CelestialBoundsCalculatorWCS(wcs) cbc.get_query()
CelestialBoundsCalculatorWCS(wcs).get_query()
- class astrafocus.targeting.tangential_plane_projector.TangentialPlaneProjector(df, wcs, mask_first=False)[source]#
Bases:
objectExamples
central_star = central_star centre = SkyCoord(ra=central_star.ra, dec=central_star.dec, unit=”deg”, frame=”icrs”)
centre = SkyCoord(ra=0, dec=0, unit=”deg”, frame=”icrs”) wcs = create_basic_wcs(center_ra=0, center_dec=-45, pixel_scale_arcsec=0.35) tangential_plane_projector = TangentialPlaneProjector(znqr, wcs) tangential_plane_projector.project(centre)
- static create_basic_wcs(center_ra: float = 0.0, center_dec: float = 0.0, pixel_scale_arcsec: float = 0.35, pixel_shape: tuple[int, int] = (2000, 2000))[source]#
Create a basic WCS object.
- Parameters:
center_ra (float) – The right ascension of the center of the field of view in degrees.
center_dec (float) – The declination of the center of the field of view in degrees.
pixel_scale_arcsec (float) – The pixel scale in arcseconds.
pixel_shape (tuple of int) – The shape of the ccd in pixels, i.e. (num_pixels_x_axis, num_pixels_y_axis). This is the equivalent to flip(image_shape). See WCS documentation for more information.
Models#
- class astrafocus.models.EllipticalMoffat2D(amplitude=1, background=0, x_0=0, y_0=0, sigma_x=1, sigma_y=1, alpha=1, theta=0.0, **kwargs)[source]
Bases:
Fittable2DModelTwo dimensional Moffat model.
- Parameters:
amplitude (float) – Amplitude of the model.
x_0 (float) – x position of the maximum of the Moffat model.
y_0 (float) – y position of the maximum of the Moffat model.
sigma_x (float) – Core width of the Moffat model.
sigma_y (float) – Core height of the Moffat model.
alpha (float) – Power index of the Moffat model.
See also
Gaussian2D,Box2DNotes
Model formula:
\[f(x, y) = B + A \left(1 + \mathrm{amplitude} \cdot \frac{\left(x - x_{0}\right)^{2} + \left(y - y_{0}\right)^{2}}{\gamma^{2}}\right)^{- \alpha}\]Examples
>>> import numpy as np >>> from astropy.modeling import fitting >>> from astrafocus.models.elliptical_moffat_2D import EllipticalMoffat2D >>> y, x = np.indices((21, 21)) >>> star_data = EllipticalMoffat2D(amplitude=1000, x_0=10.0, y_0=10.0)(x, y) >>> model = EllipticalMoffat2D(amplitude=np.max(star_data), x_0=10.0, y_0=10.0) >>> fitter = fitting.LevMarLSQFitter() >>> fit = fitter(model, x, y, star_data, estimate_jacobian=True) >>> bool(abs(fit.x_0 - 10) < 0.1) True
- alpha = Parameter('alpha', value=1.0)
- amplitude = Parameter('amplitude', value=1.0)
- background = Parameter('background', value=0.0)
- static evaluate(x, y, amplitude, background, x_0, y_0, sigma_x, sigma_y, alpha, theta)[source]
Two dimensional Moffat model function.
- static fit_deriv(x, y, amplitude, background, x_0, y_0, sigma_x, sigma_y, alpha, theta)[source]
Two dimensional Moffat model derivative with respect to parameters.
- property fwhm_x
Moffat full width at half maximum. Derivation of the formula is available in this notebook by Yoonsoo Bach.
- property input_units
This property is used to indicate what units or sets of units the evaluate method expects, and returns a dictionary mapping inputs to units (or None if any units are accepted).
Model sub-classes can also use function annotations in evaluate to indicate valid input units, in which case this property should not be overridden since it will return the input units based on the annotations.
- param_names = ('amplitude', 'background', 'x_0', 'y_0', 'sigma_x', 'sigma_y', 'alpha', 'theta')
Names of the parameters that describe models of this type.
The parameters in this tuple are in the same order they should be passed in when initializing a model of a specific type. Some types of models, such as polynomial models, have a different number of parameters depending on some other property of the model, such as the degree.
When defining a custom model class the value of this attribute is automatically set by the ~astropy.modeling.Parameter attributes defined in the class body.
- sigma_x = Parameter('sigma_x', value=1.0)
- sigma_y = Parameter('sigma_y', value=1.0)
- theta = Parameter('theta', value=0.0)
- x_0 = Parameter('x_0', value=0.0)
- y_0 = Parameter('y_0', value=0.0)
- class astrafocus.models.HalfFluxRadius2D(amplitude=1, x_0=0, y_0=0, R_0=1, scale_factor=1, **kwargs)[source]
Bases:
Disk2DExamples
>>> hfr_2D = HalfFluxRadius2D() >>> star_data=np.random.uniform(size=(20, 20)) >>> x, y = np.indices(star_data.shape) >>> _ = hfr_2D.fit(star_data, x, y, scale_factor=5)
- fit(x, y, star_data, *args, **kwargs)[source]
Source https://en.wikipedia.org/wiki/Half_flux_diameter#cite_note-4 https://www.lost-infinity.com/the-half-flux-diameter-hfd-for-a-perfectly-normal-distributed-star/
- static optimize_hfr(high_res_image, distances, hfr)[source]
- class astrafocus.models.elliptical_moffat_2D.EllipticalMoffat2D(amplitude=1, background=0, x_0=0, y_0=0, sigma_x=1, sigma_y=1, alpha=1, theta=0.0, **kwargs)[source]#
Bases:
Fittable2DModelTwo dimensional Moffat model.
- Parameters:
amplitude (float) – Amplitude of the model.
x_0 (float) – x position of the maximum of the Moffat model.
y_0 (float) – y position of the maximum of the Moffat model.
sigma_x (float) – Core width of the Moffat model.
sigma_y (float) – Core height of the Moffat model.
alpha (float) – Power index of the Moffat model.
See also
Gaussian2D,Box2DNotes
Model formula:
\[f(x, y) = B + A \left(1 + \mathrm{amplitude} \cdot \frac{\left(x - x_{0}\right)^{2} + \left(y - y_{0}\right)^{2}}{\gamma^{2}}\right)^{- \alpha}\]Examples
>>> import numpy as np >>> from astropy.modeling import fitting >>> from astrafocus.models.elliptical_moffat_2D import EllipticalMoffat2D >>> y, x = np.indices((21, 21)) >>> star_data = EllipticalMoffat2D(amplitude=1000, x_0=10.0, y_0=10.0)(x, y) >>> model = EllipticalMoffat2D(amplitude=np.max(star_data), x_0=10.0, y_0=10.0) >>> fitter = fitting.LevMarLSQFitter() >>> fit = fitter(model, x, y, star_data, estimate_jacobian=True) >>> bool(abs(fit.x_0 - 10) < 0.1) True
- alpha = Parameter('alpha', value=1.0)#
- amplitude = Parameter('amplitude', value=1.0)#
- background = Parameter('background', value=0.0)#
- static evaluate(x, y, amplitude, background, x_0, y_0, sigma_x, sigma_y, alpha, theta)[source]#
Two dimensional Moffat model function.
- static fit_deriv(x, y, amplitude, background, x_0, y_0, sigma_x, sigma_y, alpha, theta)[source]#
Two dimensional Moffat model derivative with respect to parameters.
- property fwhm_x#
Moffat full width at half maximum. Derivation of the formula is available in this notebook by Yoonsoo Bach.
- property input_units#
This property is used to indicate what units or sets of units the evaluate method expects, and returns a dictionary mapping inputs to units (or None if any units are accepted).
Model sub-classes can also use function annotations in evaluate to indicate valid input units, in which case this property should not be overridden since it will return the input units based on the annotations.
- param_names = ('amplitude', 'background', 'x_0', 'y_0', 'sigma_x', 'sigma_y', 'alpha', 'theta')#
Names of the parameters that describe models of this type.
The parameters in this tuple are in the same order they should be passed in when initializing a model of a specific type. Some types of models, such as polynomial models, have a different number of parameters depending on some other property of the model, such as the degree.
When defining a custom model class the value of this attribute is automatically set by the ~astropy.modeling.Parameter attributes defined in the class body.
- sigma_x = Parameter('sigma_x', value=1.0)#
- sigma_y = Parameter('sigma_y', value=1.0)#
- theta = Parameter('theta', value=0.0)#
- x_0 = Parameter('x_0', value=0.0)#
- y_0 = Parameter('y_0', value=0.0)#
- class astrafocus.models.half_flux_radius_2D.HalfFluxRadius2D(amplitude=1, x_0=0, y_0=0, R_0=1, scale_factor=1, **kwargs)[source]#
Bases:
Disk2DExamples
>>> hfr_2D = HalfFluxRadius2D() >>> star_data=np.random.uniform(size=(20, 20)) >>> x, y = np.indices(star_data.shape) >>> _ = hfr_2D.fit(star_data, x, y, scale_factor=5)
- fit(x, y, star_data, *args, **kwargs)[source]#
Source https://en.wikipedia.org/wiki/Half_flux_diameter#cite_note-4 https://www.lost-infinity.com/the-half-flux-diameter-hfd-for-a-perfectly-normal-distributed-star/
Database (SQL)#
- class astrafocus.sql.LocalGaiaDatabaseQuery(db_path)[source]
Bases:
objectPerform queries on the Gaia-2MASS Local Catalogue.
- Parameters:
db_path (str) – The path to the SQLite database file.
Examples
>>> from astrafocus.sql.local_gaia_database_query import LocalGaiaDatabaseQuery >>> lgdbq = LocalGaiaDatabaseQuery("path/to/db") >>> lgdbq.count_query(10, 20, 30, 40, max_phot_g_mean_mag=12)
- count_query(min_dec: float, max_dec: float, min_ra: float, max_ra: float, *, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None)[source]
Counts the number of entries in the local Gaia database within a specified range of declination and right ascension.
- Parameters:
min_dec (float) – The minimum declination value to query.
max_dec (float) – The maximum declination value to query.
min_ra (float) – The minimum right ascension value to query.
max_ra (float) – The maximum right ascension value to query.
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to filter results (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to filter results (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to filter results (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to filter results (default is None).
- Returns:
The count of entries matching the query criteria.
- Return type:
int
- Raises:
TypeError – If any of the input values is not of type float or int.
ValueError – If any of the input values is not within the specified range, or if the order of range borders is incorrect.
- query(min_dec: float, max_dec: float, min_ra: float, max_ra: float, *, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None)[source]
Queries the local Gaia database for astronomical data within a specified range of declination and right ascension. If min_ra < max_ra, the right ascension range is assumed to cross the 0/360 degree border.
- Parameters:
min_dec (float) – The minimum declination value to query.
max_dec (float) – The maximum declination value to query.
min_ra (float) – The minimum right ascension value to query.
max_ra (float) – The maximum right ascension value to query.
min_phot_g_mean_mag (float, optional) – The minimum GAIA mean magnitude to query (default is None).
max_phot_g_mean_mag (float, optional) – The maximum GAIA mean magnitude to query (default is None).
min_j_m (float, optional) – The minimum J-band magnitude to query (default is None).
max_j_m (float, optional) – The maximum J-band magnitude to query (default is None).
- Returns:
A pandas DataFrame containing the queried astronomical data.
- Return type:
pd.DataFrame
- Raises:
TypeError – If any of the input values is not of type float or int.
ValueError – If any of the input values is not within the specified range, or if the order of range borders is incorrect.]
Examples
>>> from astrafocus.sql.local_gaia_database_query import LocalGaiaDatabaseQuery >>> lgdbq = LocalGaiaDatabaseQuery("path/to/db") >>> lgdbq.count_query(10, 20, 30, 40, max_phot_g_mean_mag=12)
- class astrafocus.sql.ShardwiseQuery(db_path)[source]
Bases:
LocalGaiaDatabaseQuery- count_query_with_shard_array(dec_arr, ra_arr, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None)[source]
Count the number of stars in the Gaia-2MASS Local Catalogue using shardwise queries.
- query_with_shard_array(dec_arr, ra_arr, min_phot_g_mean_mag: float | None = None, max_phot_g_mean_mag: float | None = None, min_j_m: float | None = None, max_j_m: float | None = None)[source]
Perform shardwise queries on the Gaia-2MASS Local Catalogue.