From 5e858ef9cfe92775903cdd656759ac6b376b0b10 Mon Sep 17 00:00:00 2001 From: Alain Klotz Date: Sun, 15 Oct 2023 17:38:29 +0200 Subject: [PATCH] Prepare ASCOM device camera --- gui/t1m_guide1/t1m_guide1.py | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/guitastro/component_sensor_detector.py | 17 +++++++++++++++-- src/guitastro/filenames.py | 6 ++++++ src/guitastro/guitastrotools.py | 25 ++++++++++++++++++++----- 4 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 gui/t1m_guide1/t1m_guide1.py diff --git a/gui/t1m_guide1/t1m_guide1.py b/gui/t1m_guide1/t1m_guide1.py new file mode 100644 index 0000000..979979a --- /dev/null +++ b/gui/t1m_guide1/t1m_guide1.py @@ -0,0 +1,177 @@ +import numpy as np +import os +import sys +import time +import traceback + +paths = ["../../src", "../../../guitastro_device_ascomcam/src"] +for path in paths: + if path not in sys.path: + sys.path.insert(0,path) + +from guitastro_device_ascomcam import Device_Ascomcam + +from pymodbus.client.sync import ModbusTcpClient + +if __name__ == "__main__": + + client = ModbusTcpClient(host='172.16.10.10', port=502) + client.connect() + + name = "T1M_FinderCam" + device = "ASCOM.ASICamera2.Camera" + model = "ZWO" + serial_number = "12345" + description = "Test" + dev = Device_Ascomcam("ASCOMCAM", transport="USB", name=name, description=description, model=model, serial_number=serial_number, device=device) + # ------------------------ + real = False + dev.open(real) + # ------------------------ + cam = dev.components['camera'][1] + # ------------------------ + cam.ima.fcontext_create("t1m_guide", "Test autoguiding") + cam.ima.fcontext = "t1m_guide" + cam.ima.extension = ".fit" + rootdir0 = cam.ima.rootdir + cam.ima.rootdir = os.path.join(rootdir0, "t1m") + print(f"{cam.__repr__()}") + + # ------------------------ + if real == False: + import shutil + fname_in = os.path.join(cam.ima.rootdir, "..", "..", "data", "m57.fit") + fname_out = os.path.join(cam.ima.rootdir, "m57.fit") + shutil.copy(fname_in, fname_out) + + # ------------------------ + for k in range(4): + try: + if real: + # ------------------------ + exptime = 0.001 + cmd = f"camera SET exptime {exptime}" + print("*"*20,f"\ncmd => \"{cmd}\"") + dev.commandstring(cmd) + # ------------------------ + cmd = "camera DO ACQ START" + print("*"*20,f"\ncmd => \"{cmd}\"") + dev.commandstring(cmd) + while True: + time.sleep(0.5) + # ------------------------ + cmd = "camera GET timer" + timer = dev.commandstring(cmd) + if timer == -1: + break + else: + cam.ima.load(fname_out) + time.sleep(5) + # ----------------------- + astrotable = cam.ima.sextractor(kappa_sigma = 3) + astrotable.useFileNames = True + astrotable.fn.fcontext_create("t1m_guide") + astrotable.fn.fcontext = "t1m_guide" + astrotable.fn.rootdir = cam.ima.rootdir + fname = astrotable.fn.join("sextractor.txt") + astrotable.write(fname, format="astrotable", overwrite=True) + astrotable.keepcols(['x','y','flux', 'flag', 'fwhm']) + array = np.array([astrotable.getcol('x'),astrotable.getcol('y'),astrotable.getcol('flux'),astrotable.getcol('flag'),astrotable.getcol('fwhm')]).T + # --- Sort the matrix by the column index 2 + array_sorted = array[np.lexsort(([-1]*array[:,[2]]).T)] + INDX_X = 0 + INDX_Y = 1 + INDX_FLUX = 2 + INDX_FLAG = 3 + INDX_FWHM = 4 + astrotable.setcol('x', array_sorted[:,INDX_X]) + astrotable.setcol('y', array_sorted[:,INDX_Y]) + astrotable.setcol('flux', array_sorted[:,INDX_FLUX]) + astrotable.setcol('flag', array_sorted[:,INDX_FLAG]) + astrotable.setcol('fwhm', array_sorted[:,INDX_FWHM]) + fname = astrotable.fn.join("sextractor_sorted.txt") + astrotable.write(fname, format="astrotable", overwrite=True) + # --- + naxis1 = cam.ima.getkwd("NAXIS1") + naxis2 = cam.ima.getkwd("NAXIS2") + border = 50 + xmin = border + xmax = naxis1-border + ymin = border + ymax = naxis2-border + ident_limit = 5 + ident_limit2 = ident_limit*ident_limit + nb_star = 5 + # --- + if k == 0: + nlig, ncol = array_sorted.shape + valids = np.ones(nlig) + for klig in range(nlig): + if array_sorted[klig, INDX_FLAG] > 0: + valids[klig] = 0 + x = array_sorted[klig, INDX_X] + if x < xmin or x > xmax: + valids[klig] = 0 + y = array_sorted[klig, INDX_Y] + if y < ymin or y > ymax: + valids[klig] = 0 + array_sorted0 = array_sorted.copy() + else: + # --- match stars and compute dx, dy + nlig0, ncol0 = array_sorted0.shape + nlig, ncol = array_sorted.shape + decals = [] + kstar = 0 + for klig0 in range(nlig0): + if kstar > nb_star: + break + if valids[klig0] == 0: + continue + x0 = array_sorted0[klig0, INDX_X] + y0 = array_sorted0[klig0, INDX_Y] + for klig in range(nlig): + x = array_sorted[klig, INDX_X] + y = array_sorted[klig, INDX_Y] + if not real: + x += 0.1*np.random.normal(1) + y += 0.1*np.random.normal(1) + dx = x - x0 + dy = y - y0 + d2 = dx*dx + dy*dy + if d2 < ident_limit2: + # --- same star + decal = [dx, dy, x0, y0] + decals.append(decal) + continue + kstar += 1 + decals = np.array(decals) + #print(f"{decals=}") + # --- compute median of dx, dy + dxs = decals[:,0] + dys = decals[:,1] + dx_med = np.median(dxs) + dy_med = np.median(dys) + print(f"{dx_med=:.2f} {dy_med=:.2f}") + # ---------------------------- + if dx_med < 0: + m_alpha = 54 + else: + m_alpha = 55 + if dy_med < 0: + m_delta = 50 + else: + m_delta = 51 + client.write_coils(m_alpha, True, unit=0) + client.write_coils(m_delta, True, unit=0) + time.sleep(0.3) + client.write_coils(m_alpha, False, unit=0) + client.write_coils(m_delta, False, unit=0) + # ---------------------------- + + + except: + traceback.print_exc(file=sys.stdout) + # ------------------------ + print("*"*20,"\nClose") + dev.close() + diff --git a/src/guitastro/component_sensor_detector.py b/src/guitastro/component_sensor_detector.py index ecc4fd5..09b5133 100644 --- a/src/guitastro/component_sensor_detector.py +++ b/src/guitastro/component_sensor_detector.py @@ -37,10 +37,18 @@ class ComponentSensorDetectorException(GuitastroException): ERR_DETECTOR_IS_EXPOSING = 1 ERR_DETECTOR_IS_READING = 2 + ERR_CANNOT_SET_TEMPERATURE = 3 + ERR_SUBKEY_COOLER_NOT_VALID = 4 + ERR_CANNOT_SET_GAIN = 5 + ERR_ACQUISTION_TIMEOUT = 6 - errors = [""]*3 + errors = [""]*7 errors[ERR_DETECTOR_IS_EXPOSING] = "The detector is in exposure. Cannot start other exposures" errors[ERR_DETECTOR_IS_READING] = "The detector is reading. Cannot start other exposures" + errors[ERR_CANNOT_SET_TEMPERATURE] = "Cannot set the temparture of this camera" + errors[ERR_SUBKEY_COOLER_NOT_VALID] = "Sub key of cooler is not valid" + errors[ERR_CANNOT_SET_GAIN] = "Cannont set the gain of this camera" + errors[ERR_ACQUISTION_TIMEOUT] = "Acquisition timeout" class ComponentSensorDetector(ComponentSensorDetectorException, Component, GuitastroTools): @@ -105,7 +113,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita self.siteobs = Siteobs(self._sensor_params["SITE"]) # === Image in memory self.ima = Ima() - self.ima.longitude(self.siteobs.longitude) + self.ima.longitude = self.siteobs.longitude if str(type(self._sensor_params["ETC"])) == "": self.ima.etc = self._sensor_params["ETC"] # === Name @@ -122,6 +130,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita param = {} param['exptime'] = 0.1 param['binning'] = [1, 1] + param['status'] = self.SENSOR_STATE_UNKNOWN self._queue.put(param) # ------------ prop @@ -164,6 +173,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita return "" def _do_acq(self, *args, **kwargs): + """ For real and simu + """ result = None operation = args[0].upper() # --- Manage sub operations of ACQ @@ -179,6 +190,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita binning = param['binning'] # TBD # --- call the real + param['status'] = self.SENSOR_STATE_EXPOSING + param = self.database.query(param) if self.real: result = self._my_do_acq(*args, **kwargs) return result diff --git a/src/guitastro/filenames.py b/src/guitastro/filenames.py index 9eb250c..3dc5ed5 100644 --- a/src/guitastro/filenames.py +++ b/src/guitastro/filenames.py @@ -444,6 +444,9 @@ class FileNames(FileNamesException, GuitastroTools): fn = FileNames() fn.naming("PyROS.img.1") + Raises: + FileNamesException: The naming is not found. + """ if len(args) >= 1: new_naming = args[0] @@ -966,6 +969,9 @@ class FileNames(FileNamesException, GuitastroTools): params = fn.naming_get("L0A_20221109_235406123456_1_TNC_CH1_0123456789_001_012") The answer (params dict) should be {'ftype': 'L0A', 'date': '20221109', 'time': '235406123456', 'version': '1', 'unit': 'TNC', 'channel': 'CH1', 'id_seq': '0123456789', 'plane': '001', 'frame': '012'} + + Raises: + FileNamesException: Bad file name rules. """ param = {} see_rules = self._see_naming_rules diff --git a/src/guitastro/guitastrotools.py b/src/guitastro/guitastrotools.py index 6e81e56..f2dbbfe 100644 --- a/src/guitastro/guitastrotools.py +++ b/src/guitastro/guitastrotools.py @@ -30,6 +30,14 @@ if os.path.exists(conf_guitastro['path_products']) == False: conf_guitastro['path_products'] = os.path.join(path_tmp,"guitastro","products") os.makedirs(conf_guitastro['path_products'], exist_ok=True) +# - This condition is to avoid to download de421.bsp if no internet connection +if not os.path.exists(os.path.join(conf_guitastro['path'],"de421.bsp")): + de421_out = os.path.join(conf_guitastro['path'],"de421.bsp") + de421_in = os.path.join(conf_guitastro['path'],"..", "..","resources","solar_system","de421.bsp") + print(f"{de421_in=}") + print(f"{de421_out=}") + shutil.copy(de421_in, de421_out) + # ##################################################################### # ##################################################################### # ##################################################################### @@ -449,7 +457,7 @@ class GuitastroDev(GuitastroDevException): shutil.rmtree(path_to) except: pass - ignore = shutil.ignore_patterns('__pycache__', 'build', "de421.bsp") + ignore = shutil.ignore_patterns('__pycache__', '.git', 'build', "de421.bsp") shutil.copytree(path_from, path_to, ignore=ignore) # --- List all the files in the module root = path_to @@ -478,11 +486,14 @@ class GuitastroDev(GuitastroDevException): # --- Change directories with the new module name for inpd in inpds: outd = inpd.replace(from_name, to_name) - os.rename(inpd, outd) + try: + os.rename(inpd, outd) + except: + pass # --- List all the files in the module root = path_to inpfiles = [os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files] - # --- Collect all the possibilities² to find input name + # --- Collect all the possibilities to find input name inpnames = [] inpnameu = from_name.upper() inpnamel = len(from_name) @@ -512,7 +523,11 @@ class GuitastroDev(GuitastroDevException): # --- Replace for inpfilemod in inpfilemods: with open(inpfilemod, "r") as fid: - lines = fid.read() + print(f"{inpfilemod=}") + try: + lines = fid.read() + except: + continue for inpname in inpnames: if inpname == from_capname: outname = to_capname @@ -648,7 +663,7 @@ if __name__ == "__main__": Create initial source code of a new device. """ gta1 = GuitastroDev() - res = gta1.create_device_module("Flipro", "Quickaudine") + res = gta1.create_device_module("Flipro", "Ascomcam") print(f"res={res}") if example == 2: -- libgit2 0.21.2