API
 
Loading...
Searching...
No Matches
sparkleTracker.py
Go to the documentation of this file.
1import sys
2import logging
3from enum import Enum
4import time
5import numpy as np
6import datetime
7import os
8import hcipy as hp
9
10import xconf
11
12from magaox.indi.device import XDevice, BaseConfig
13from magaox.camera import XCam
14from magaox.deformable_mirror import XDeformableMirror
15from magaox.constants import StateCodes
16from magaox.state_manager import XStateMachine
17
18from purepyindi2 import device, properties, constants
19from purepyindi2.messages import DefNumber, DefSwitch, DefLight, DefText
20
21
22class XCorrShift():
23 def __init__(self, reference_image, domain_pixels=480, domain_size=40, filter_size=None):
24 self._reference_image = reference_image
25 self._xgrid = hp.make_pupil_grid(domain_pixels, domain_size)
26
27 self._fft = hp.FastFourierTransform(self._reference_image.grid)
28 self._mft = hp.MatrixFourierTransform(self._xgrid, self._fft.output_grid)
29
30 self._filter_size = filter_size
31 if filter_size is not None:
32 # Change this to a super gaussian filter to remove ringing.
33 self._spatial_filter = hp.make_circular_aperture(self._filter_size)(self._fft.output_grid)
34 else:
35 self._spatial_filter = 1
36
37 self._kernel = np.conj(self._fft.forward(self._reference_image + 0j))
38
39 def cross_correlate(self, image):
40 xcorr = np.real(self._mft.backward(self._fft.forward(image + 0j) * self._spatial_filter * self._kernel))
41 return xcorr
42
43 def measure(self, image):
44 # Do a cross-correlation and find the peak pixel
45 # TODO: implement sub-pixel precision with polynomial fitting
46 xcorr = self.cross_correlate(image)
47 indx_max = np.argmax(xcorr)
48 return self._xgrid.points[indx_max]
49
50@xconf.config
52 """
53 """
54 shmim : str = xconf.field(help="Name of the camera device (specifically, the associated shmim, if different).")
55 dark_shmim : str = xconf.field(help="Name of the dark frame shmim associated with this camera device.")
56 stagepos : float = xconf.field(help="Stage position for pupil control.")
57
58@xconf.config
60 """
61 """
62 path : str = xconf.field(help="Path to the calibration files for the pupil alignment.")
63 fwpupil_modes : list[str] = xconf.field(help="List of calibrated fwpupil masks.")
64 fwlyot_modes : list[str] = xconf.field(help="List of calibrated fwlyot masks.")
65
66@xconf.config
67class sparkleTrackerConfig(BaseConfig):
68 """Sparkle trackker config.
69 """
70 camera : CameraConfig = xconf.field(help="Camera to use")
71 calibration : CalibrationConfig = xconf.field(help='Calibration parameters')
72
73class States(Enum):
74 IDLE = 0
75 TRACK = 1
76 MEASURE = 2
77
78class sparkleTracker(XDevice):
79 config : sparkleTrackerConfig
80
81 def setup(self):
82 self.log.debug(f"I was configured! See? {self.config=}")
83
84 self.log.info("Found camera: {:s}".format(self.config.camera.shmim))
85 self.camera = XCam(self.config.camera.shmim, use_hcipy=True)
86
87 fsm = properties.TextVector(name='fsm')
88 fsm.add_element(DefText(name='state', _value=StateCodes.INITIALIZED.name))
89 self.add_property(fsm)
90
91 self._state_names = ['idle', 'track', 'measure']
92 self._state_callbacks = [None, self.track, self.measure]
93 self._state_machine = XStateMachine(self, self._state_names, States, self._state_callbacks)
94
95 self.log.info(f'sparkleTracker app is fully setup.')
96
97 def calculate_shift(self):
98 pass
99
100 def track(self):
101 pass
102
103 def loop(self):
104 '''
105 '''
106 self._state_machine.loop()
107 self.update_properties()
__init__(self, reference_image, domain_pixels=480, domain_size=40, filter_size=None)
sparkleTrackerConfig config