Commit 5e858ef9cfe92775903cdd656759ac6b376b0b10

Authored by Alain Klotz
1 parent 55ae73d4
Exists in master

Prepare ASCOM device camera

gui/t1m_guide1/t1m_guide1.py 0 → 100644
@@ -0,0 +1,177 @@ @@ -0,0 +1,177 @@
  1 +import numpy as np
  2 +import os
  3 +import sys
  4 +import time
  5 +import traceback
  6 +
  7 +paths = ["../../src", "../../../guitastro_device_ascomcam/src"]
  8 +for path in paths:
  9 + if path not in sys.path:
  10 + sys.path.insert(0,path)
  11 +
  12 +from guitastro_device_ascomcam import Device_Ascomcam
  13 +
  14 +from pymodbus.client.sync import ModbusTcpClient
  15 +
  16 +if __name__ == "__main__":
  17 +
  18 + client = ModbusTcpClient(host='172.16.10.10', port=502)
  19 + client.connect()
  20 +
  21 + name = "T1M_FinderCam"
  22 + device = "ASCOM.ASICamera2.Camera"
  23 + model = "ZWO"
  24 + serial_number = "12345"
  25 + description = "Test"
  26 + dev = Device_Ascomcam("ASCOMCAM", transport="USB", name=name, description=description, model=model, serial_number=serial_number, device=device)
  27 + # ------------------------
  28 + real = False
  29 + dev.open(real)
  30 + # ------------------------
  31 + cam = dev.components['camera'][1]
  32 + # ------------------------
  33 + cam.ima.fcontext_create("t1m_guide", "Test autoguiding")
  34 + cam.ima.fcontext = "t1m_guide"
  35 + cam.ima.extension = ".fit"
  36 + rootdir0 = cam.ima.rootdir
  37 + cam.ima.rootdir = os.path.join(rootdir0, "t1m")
  38 + print(f"{cam.__repr__()}")
  39 +
  40 + # ------------------------
  41 + if real == False:
  42 + import shutil
  43 + fname_in = os.path.join(cam.ima.rootdir, "..", "..", "data", "m57.fit")
  44 + fname_out = os.path.join(cam.ima.rootdir, "m57.fit")
  45 + shutil.copy(fname_in, fname_out)
  46 +
  47 + # ------------------------
  48 + for k in range(4):
  49 + try:
  50 + if real:
  51 + # ------------------------
  52 + exptime = 0.001
  53 + cmd = f"camera SET exptime {exptime}"
  54 + print("*"*20,f"\ncmd => \"{cmd}\"")
  55 + dev.commandstring(cmd)
  56 + # ------------------------
  57 + cmd = "camera DO ACQ START"
  58 + print("*"*20,f"\ncmd => \"{cmd}\"")
  59 + dev.commandstring(cmd)
  60 + while True:
  61 + time.sleep(0.5)
  62 + # ------------------------
  63 + cmd = "camera GET timer"
  64 + timer = dev.commandstring(cmd)
  65 + if timer == -1:
  66 + break
  67 + else:
  68 + cam.ima.load(fname_out)
  69 + time.sleep(5)
  70 + # -----------------------
  71 + astrotable = cam.ima.sextractor(kappa_sigma = 3)
  72 + astrotable.useFileNames = True
  73 + astrotable.fn.fcontext_create("t1m_guide")
  74 + astrotable.fn.fcontext = "t1m_guide"
  75 + astrotable.fn.rootdir = cam.ima.rootdir
  76 + fname = astrotable.fn.join("sextractor.txt")
  77 + astrotable.write(fname, format="astrotable", overwrite=True)
  78 + astrotable.keepcols(['x','y','flux', 'flag', 'fwhm'])
  79 + array = np.array([astrotable.getcol('x'),astrotable.getcol('y'),astrotable.getcol('flux'),astrotable.getcol('flag'),astrotable.getcol('fwhm')]).T
  80 + # --- Sort the matrix by the column index 2
  81 + array_sorted = array[np.lexsort(([-1]*array[:,[2]]).T)]
  82 + INDX_X = 0
  83 + INDX_Y = 1
  84 + INDX_FLUX = 2
  85 + INDX_FLAG = 3
  86 + INDX_FWHM = 4
  87 + astrotable.setcol('x', array_sorted[:,INDX_X])
  88 + astrotable.setcol('y', array_sorted[:,INDX_Y])
  89 + astrotable.setcol('flux', array_sorted[:,INDX_FLUX])
  90 + astrotable.setcol('flag', array_sorted[:,INDX_FLAG])
  91 + astrotable.setcol('fwhm', array_sorted[:,INDX_FWHM])
  92 + fname = astrotable.fn.join("sextractor_sorted.txt")
  93 + astrotable.write(fname, format="astrotable", overwrite=True)
  94 + # ---
  95 + naxis1 = cam.ima.getkwd("NAXIS1")
  96 + naxis2 = cam.ima.getkwd("NAXIS2")
  97 + border = 50
  98 + xmin = border
  99 + xmax = naxis1-border
  100 + ymin = border
  101 + ymax = naxis2-border
  102 + ident_limit = 5
  103 + ident_limit2 = ident_limit*ident_limit
  104 + nb_star = 5
  105 + # ---
  106 + if k == 0:
  107 + nlig, ncol = array_sorted.shape
  108 + valids = np.ones(nlig)
  109 + for klig in range(nlig):
  110 + if array_sorted[klig, INDX_FLAG] > 0:
  111 + valids[klig] = 0
  112 + x = array_sorted[klig, INDX_X]
  113 + if x < xmin or x > xmax:
  114 + valids[klig] = 0
  115 + y = array_sorted[klig, INDX_Y]
  116 + if y < ymin or y > ymax:
  117 + valids[klig] = 0
  118 + array_sorted0 = array_sorted.copy()
  119 + else:
  120 + # --- match stars and compute dx, dy
  121 + nlig0, ncol0 = array_sorted0.shape
  122 + nlig, ncol = array_sorted.shape
  123 + decals = []
  124 + kstar = 0
  125 + for klig0 in range(nlig0):
  126 + if kstar > nb_star:
  127 + break
  128 + if valids[klig0] == 0:
  129 + continue
  130 + x0 = array_sorted0[klig0, INDX_X]
  131 + y0 = array_sorted0[klig0, INDX_Y]
  132 + for klig in range(nlig):
  133 + x = array_sorted[klig, INDX_X]
  134 + y = array_sorted[klig, INDX_Y]
  135 + if not real:
  136 + x += 0.1*np.random.normal(1)
  137 + y += 0.1*np.random.normal(1)
  138 + dx = x - x0
  139 + dy = y - y0
  140 + d2 = dx*dx + dy*dy
  141 + if d2 < ident_limit2:
  142 + # --- same star
  143 + decal = [dx, dy, x0, y0]
  144 + decals.append(decal)
  145 + continue
  146 + kstar += 1
  147 + decals = np.array(decals)
  148 + #print(f"{decals=}")
  149 + # --- compute median of dx, dy
  150 + dxs = decals[:,0]
  151 + dys = decals[:,1]
  152 + dx_med = np.median(dxs)
  153 + dy_med = np.median(dys)
  154 + print(f"{dx_med=:.2f} {dy_med=:.2f}")
  155 + # ----------------------------
  156 + if dx_med < 0:
  157 + m_alpha = 54
  158 + else:
  159 + m_alpha = 55
  160 + if dy_med < 0:
  161 + m_delta = 50
  162 + else:
  163 + m_delta = 51
  164 + client.write_coils(m_alpha, True, unit=0)
  165 + client.write_coils(m_delta, True, unit=0)
  166 + time.sleep(0.3)
  167 + client.write_coils(m_alpha, False, unit=0)
  168 + client.write_coils(m_delta, False, unit=0)
  169 + # ----------------------------
  170 +
  171 +
  172 + except:
  173 + traceback.print_exc(file=sys.stdout)
  174 + # ------------------------
  175 + print("*"*20,"\nClose")
  176 + dev.close()
  177 +
src/guitastro/component_sensor_detector.py
@@ -37,10 +37,18 @@ class ComponentSensorDetectorException(GuitastroException): @@ -37,10 +37,18 @@ class ComponentSensorDetectorException(GuitastroException):
37 37
38 ERR_DETECTOR_IS_EXPOSING = 1 38 ERR_DETECTOR_IS_EXPOSING = 1
39 ERR_DETECTOR_IS_READING = 2 39 ERR_DETECTOR_IS_READING = 2
  40 + ERR_CANNOT_SET_TEMPERATURE = 3
  41 + ERR_SUBKEY_COOLER_NOT_VALID = 4
  42 + ERR_CANNOT_SET_GAIN = 5
  43 + ERR_ACQUISTION_TIMEOUT = 6
40 44
41 - errors = [""]*3 45 + errors = [""]*7
42 errors[ERR_DETECTOR_IS_EXPOSING] = "The detector is in exposure. Cannot start other exposures" 46 errors[ERR_DETECTOR_IS_EXPOSING] = "The detector is in exposure. Cannot start other exposures"
43 errors[ERR_DETECTOR_IS_READING] = "The detector is reading. Cannot start other exposures" 47 errors[ERR_DETECTOR_IS_READING] = "The detector is reading. Cannot start other exposures"
  48 + errors[ERR_CANNOT_SET_TEMPERATURE] = "Cannot set the temparture of this camera"
  49 + errors[ERR_SUBKEY_COOLER_NOT_VALID] = "Sub key of cooler is not valid"
  50 + errors[ERR_CANNOT_SET_GAIN] = "Cannont set the gain of this camera"
  51 + errors[ERR_ACQUISTION_TIMEOUT] = "Acquisition timeout"
44 52
45 53
46 class ComponentSensorDetector(ComponentSensorDetectorException, Component, GuitastroTools): 54 class ComponentSensorDetector(ComponentSensorDetectorException, Component, GuitastroTools):
@@ -105,7 +113,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita @@ -105,7 +113,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita
105 self.siteobs = Siteobs(self._sensor_params["SITE"]) 113 self.siteobs = Siteobs(self._sensor_params["SITE"])
106 # === Image in memory 114 # === Image in memory
107 self.ima = Ima() 115 self.ima = Ima()
108 - self.ima.longitude(self.siteobs.longitude) 116 + self.ima.longitude = self.siteobs.longitude
109 if str(type(self._sensor_params["ETC"])) == "<class 'etc.ExposureTimeCalculator'>": 117 if str(type(self._sensor_params["ETC"])) == "<class 'etc.ExposureTimeCalculator'>":
110 self.ima.etc = self._sensor_params["ETC"] 118 self.ima.etc = self._sensor_params["ETC"]
111 # === Name 119 # === Name
@@ -122,6 +130,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita @@ -122,6 +130,7 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita
122 param = {} 130 param = {}
123 param['exptime'] = 0.1 131 param['exptime'] = 0.1
124 param['binning'] = [1, 1] 132 param['binning'] = [1, 1]
  133 + param['status'] = self.SENSOR_STATE_UNKNOWN
125 self._queue.put(param) 134 self._queue.put(param)
126 135
127 # ------------ prop 136 # ------------ prop
@@ -164,6 +173,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita @@ -164,6 +173,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita
164 return "" 173 return ""
165 174
166 def _do_acq(self, *args, **kwargs): 175 def _do_acq(self, *args, **kwargs):
  176 + """ For real and simu
  177 + """
167 result = None 178 result = None
168 operation = args[0].upper() 179 operation = args[0].upper()
169 # --- Manage sub operations of ACQ 180 # --- Manage sub operations of ACQ
@@ -179,6 +190,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita @@ -179,6 +190,8 @@ class ComponentSensorDetector(ComponentSensorDetectorException, Component, Guita
179 binning = param['binning'] 190 binning = param['binning']
180 # TBD 191 # TBD
181 # --- call the real 192 # --- call the real
  193 + param['status'] = self.SENSOR_STATE_EXPOSING
  194 + param = self.database.query(param)
182 if self.real: 195 if self.real:
183 result = self._my_do_acq(*args, **kwargs) 196 result = self._my_do_acq(*args, **kwargs)
184 return result 197 return result
src/guitastro/filenames.py
@@ -444,6 +444,9 @@ class FileNames(FileNamesException, GuitastroTools): @@ -444,6 +444,9 @@ class FileNames(FileNamesException, GuitastroTools):
444 fn = FileNames() 444 fn = FileNames()
445 fn.naming("PyROS.img.1") 445 fn.naming("PyROS.img.1")
446 446
  447 + Raises:
  448 + FileNamesException: The naming is not found.
  449 +
447 """ 450 """
448 if len(args) >= 1: 451 if len(args) >= 1:
449 new_naming = args[0] 452 new_naming = args[0]
@@ -966,6 +969,9 @@ class FileNames(FileNamesException, GuitastroTools): @@ -966,6 +969,9 @@ class FileNames(FileNamesException, GuitastroTools):
966 params = fn.naming_get("L0A_20221109_235406123456_1_TNC_CH1_0123456789_001_012") 969 params = fn.naming_get("L0A_20221109_235406123456_1_TNC_CH1_0123456789_001_012")
967 970
968 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'} 971 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'}
  972 +
  973 + Raises:
  974 + FileNamesException: Bad file name rules.
969 """ 975 """
970 param = {} 976 param = {}
971 see_rules = self._see_naming_rules 977 see_rules = self._see_naming_rules
src/guitastro/guitastrotools.py
@@ -30,6 +30,14 @@ if os.path.exists(conf_guitastro[&#39;path_products&#39;]) == False: @@ -30,6 +30,14 @@ if os.path.exists(conf_guitastro[&#39;path_products&#39;]) == False:
30 conf_guitastro['path_products'] = os.path.join(path_tmp,"guitastro","products") 30 conf_guitastro['path_products'] = os.path.join(path_tmp,"guitastro","products")
31 os.makedirs(conf_guitastro['path_products'], exist_ok=True) 31 os.makedirs(conf_guitastro['path_products'], exist_ok=True)
32 32
  33 +# - This condition is to avoid to download de421.bsp if no internet connection
  34 +if not os.path.exists(os.path.join(conf_guitastro['path'],"de421.bsp")):
  35 + de421_out = os.path.join(conf_guitastro['path'],"de421.bsp")
  36 + de421_in = os.path.join(conf_guitastro['path'],"..", "..","resources","solar_system","de421.bsp")
  37 + print(f"{de421_in=}")
  38 + print(f"{de421_out=}")
  39 + shutil.copy(de421_in, de421_out)
  40 +
33 # ##################################################################### 41 # #####################################################################
34 # ##################################################################### 42 # #####################################################################
35 # ##################################################################### 43 # #####################################################################
@@ -449,7 +457,7 @@ class GuitastroDev(GuitastroDevException): @@ -449,7 +457,7 @@ class GuitastroDev(GuitastroDevException):
449 shutil.rmtree(path_to) 457 shutil.rmtree(path_to)
450 except: 458 except:
451 pass 459 pass
452 - ignore = shutil.ignore_patterns('__pycache__', 'build', "de421.bsp") 460 + ignore = shutil.ignore_patterns('__pycache__', '.git', 'build', "de421.bsp")
453 shutil.copytree(path_from, path_to, ignore=ignore) 461 shutil.copytree(path_from, path_to, ignore=ignore)
454 # --- List all the files in the module 462 # --- List all the files in the module
455 root = path_to 463 root = path_to
@@ -478,11 +486,14 @@ class GuitastroDev(GuitastroDevException): @@ -478,11 +486,14 @@ class GuitastroDev(GuitastroDevException):
478 # --- Change directories with the new module name 486 # --- Change directories with the new module name
479 for inpd in inpds: 487 for inpd in inpds:
480 outd = inpd.replace(from_name, to_name) 488 outd = inpd.replace(from_name, to_name)
481 - os.rename(inpd, outd) 489 + try:
  490 + os.rename(inpd, outd)
  491 + except:
  492 + pass
482 # --- List all the files in the module 493 # --- List all the files in the module
483 root = path_to 494 root = path_to
484 inpfiles = [os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files] 495 inpfiles = [os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files]
485 - # --- Collect all the possibilities² to find input name 496 + # --- Collect all the possibilities to find input name
486 inpnames = [] 497 inpnames = []
487 inpnameu = from_name.upper() 498 inpnameu = from_name.upper()
488 inpnamel = len(from_name) 499 inpnamel = len(from_name)
@@ -512,7 +523,11 @@ class GuitastroDev(GuitastroDevException): @@ -512,7 +523,11 @@ class GuitastroDev(GuitastroDevException):
512 # --- Replace 523 # --- Replace
513 for inpfilemod in inpfilemods: 524 for inpfilemod in inpfilemods:
514 with open(inpfilemod, "r") as fid: 525 with open(inpfilemod, "r") as fid:
515 - lines = fid.read() 526 + print(f"{inpfilemod=}")
  527 + try:
  528 + lines = fid.read()
  529 + except:
  530 + continue
516 for inpname in inpnames: 531 for inpname in inpnames:
517 if inpname == from_capname: 532 if inpname == from_capname:
518 outname = to_capname 533 outname = to_capname
@@ -648,7 +663,7 @@ if __name__ == &quot;__main__&quot;: @@ -648,7 +663,7 @@ if __name__ == &quot;__main__&quot;:
648 Create initial source code of a new device. 663 Create initial source code of a new device.
649 """ 664 """
650 gta1 = GuitastroDev() 665 gta1 = GuitastroDev()
651 - res = gta1.create_device_module("Flipro", "Quickaudine") 666 + res = gta1.create_device_module("Flipro", "Ascomcam")
652 print(f"res={res}") 667 print(f"res={res}")
653 668
654 if example == 2: 669 if example == 2: