Commit 6a4ed2c2c06ecfe730948620a9abed2d75c3bd2d
1 parent
1cff4249
Exists in
dev
Start the AgentImagesCalibrator coding.
Showing
5 changed files
with
407 additions
and
15 deletions
Show diff stats
privatedev/config/tnc/observatory_tnc.yml
@@ -322,6 +322,11 @@ OBSERVATORY: | @@ -322,6 +322,11 @@ OBSERVATORY: | ||
322 | computer: MainComputer | 322 | computer: MainComputer |
323 | protocol: private/plugin/agent/AgentScheduler.py | 323 | protocol: private/plugin/agent/AgentScheduler.py |
324 | 324 | ||
325 | + # SF10-CAL (for AKz) | ||
326 | + - AGENT: | ||
327 | + name: AgentImagesCalibrator | ||
328 | + computer: MainComputer | ||
329 | + | ||
325 | # SF11-IPC (for AKz) | 330 | # SF11-IPC (for AKz) |
326 | - AGENT: | 331 | - AGENT: |
327 | name: AgentImagesProcessor | 332 | name: AgentImagesProcessor |
pyros.py
@@ -61,6 +61,7 @@ AGENTS = { | @@ -61,6 +61,7 @@ AGENTS = { | ||
61 | "AgentSP": "scientific_programs", | 61 | "AgentSP": "scientific_programs", |
62 | "AgentScheduler": "scheduler", | 62 | "AgentScheduler": "scheduler", |
63 | "AgentImagesProcessor": "observation_manager", | 63 | "AgentImagesProcessor": "observation_manager", |
64 | + "AgentImagesCalibrator": "observation_manager", | ||
64 | "agentSST": "agent", | 65 | "agentSST": "agent", |
65 | "Agent": "agent", | 66 | "Agent": "agent", |
66 | "Agent2": "agent", | 67 | "Agent2": "agent", |
src/core/pyros_django/obsconfig/obsconfig_class.py
@@ -33,8 +33,8 @@ class OBSConfig: | @@ -33,8 +33,8 @@ class OBSConfig: | ||
33 | "AgentM":None | 33 | "AgentM":None |
34 | 34 | ||
35 | } | 35 | } |
36 | - | ||
37 | - | 36 | + |
37 | + | ||
38 | def verify_if_pickle_needs_to_be_updated(self, observatory_config_file) -> bool: | 38 | def verify_if_pickle_needs_to_be_updated(self, observatory_config_file) -> bool: |
39 | """ | 39 | """ |
40 | 40 | ||
@@ -159,7 +159,7 @@ class OBSConfig: | @@ -159,7 +159,7 @@ class OBSConfig: | ||
159 | 159 | ||
160 | Args: | 160 | Args: |
161 | yaml_file (str): Path to the config_file to be validated | 161 | yaml_file (str): Path to the config_file to be validated |
162 | - schema_file (str): Path to the schema file | 162 | + schema_file (str): Path to the schema file |
163 | 163 | ||
164 | Returns: | 164 | Returns: |
165 | dict: dictionary of the config file (with values) | 165 | dict: dictionary of the config file (with values) |
@@ -195,7 +195,7 @@ class OBSConfig: | @@ -195,7 +195,7 @@ class OBSConfig: | ||
195 | 195 | ||
196 | Args: | 196 | Args: |
197 | yaml_file (str): Path to the config_file to be validated | 197 | yaml_file (str): Path to the config_file to be validated |
198 | - schema_file (str): Path to the schema file | 198 | + schema_file (str): Path to the schema file |
199 | 199 | ||
200 | Returns: | 200 | Returns: |
201 | any: boolean (True) if the configuration is valid according the schema or a list of error otherwise | 201 | any: boolean (True) if the configuration is valid according the schema or a list of error otherwise |
@@ -333,7 +333,7 @@ class OBSConfig: | @@ -333,7 +333,7 @@ class OBSConfig: | ||
333 | 333 | ||
334 | def get_devices_names_and_file(self) -> dict: | 334 | def get_devices_names_and_file(self) -> dict: |
335 | """ | 335 | """ |
336 | - Return a dictionary giving the device file name by the device name | 336 | + Return a dictionary giving the device file name by the device name |
337 | Returns: | 337 | Returns: |
338 | dict: key is device name, value is file name | 338 | dict: key is device name, value is file name |
339 | """ | 339 | """ |
@@ -549,7 +549,7 @@ class OBSConfig: | @@ -549,7 +549,7 @@ class OBSConfig: | ||
549 | self.unit_name = self.get_units_name()[0] | 549 | self.unit_name = self.get_units_name()[0] |
550 | else: | 550 | else: |
551 | self.unit_name = unit_name | 551 | self.unit_name = unit_name |
552 | - # call get_agents so the class will check if mandatory agents are in the obsconfig | 552 | + # call get_agents so the class will check if mandatory agents are in the obsconfig |
553 | self.get_agents(self.unit_name) | 553 | self.get_agents(self.unit_name) |
554 | 554 | ||
555 | def get_obs_name(self) -> str: | 555 | def get_obs_name(self) -> str: |
@@ -630,7 +630,7 @@ class OBSConfig: | @@ -630,7 +630,7 @@ class OBSConfig: | ||
630 | 630 | ||
631 | def get_agents(self, unit_name) -> dict: | 631 | def get_agents(self, unit_name) -> dict: |
632 | """ | 632 | """ |
633 | - return dictionary of agents | 633 | + return dictionary of agents |
634 | 634 | ||
635 | Args: | 635 | Args: |
636 | unit_name (str): name of the unit | 636 | unit_name (str): name of the unit |
@@ -695,7 +695,7 @@ class OBSConfig: | @@ -695,7 +695,7 @@ class OBSConfig: | ||
695 | Return information of the given channel name of a unit | 695 | Return information of the given channel name of a unit |
696 | 696 | ||
697 | Args: | 697 | Args: |
698 | - unit_name (str): Name of the unit | 698 | + unit_name (str): Name of the unit |
699 | channel_name (str): name of the channel | 699 | channel_name (str): name of the channel |
700 | 700 | ||
701 | Returns: | 701 | Returns: |
@@ -727,6 +727,32 @@ class OBSConfig: | @@ -727,6 +727,32 @@ class OBSConfig: | ||
727 | topology[key] = branch | 727 | topology[key] = branch |
728 | return topology | 728 | return topology |
729 | 729 | ||
730 | + def get_image_calibrations(self, unit_name: str, channel_name: str, category: str) -> dict: | ||
731 | + """ | ||
732 | + Return dictionary of image calibrations | ||
733 | + | ||
734 | + Args: | ||
735 | + unit_name (str): name of the unit | ||
736 | + channel_name (str): name of the channel | ||
737 | + category (str): category name of image calibration (BI, DA, FL) | ||
738 | + | ||
739 | + Returns: | ||
740 | + dict: dictionary of image calibrations | ||
741 | + """ | ||
742 | + unit = self.get_unit_by_name(unit_name) | ||
743 | + info = {} | ||
744 | + info["image_calibrations"] = {} | ||
745 | + for kserie in range(len(unit["IMAGE_CALIBRATIONS"]["SERIES"])): | ||
746 | + scategory = unit["IMAGE_CALIBRATIONS"]["SERIES"][kserie]["category"] | ||
747 | + if category == scategory: | ||
748 | + for kchannel in range(len(unit["IMAGE_CALIBRATIONS"]["SERIES"][kserie]["CHANNELS"])): | ||
749 | + schannel = unit["IMAGE_CALIBRATIONS"]["SERIES"][kserie]["CHANNELS"][kchannel]["name"] | ||
750 | + if channel_name == schannel: | ||
751 | + dico = unit["IMAGE_CALIBRATIONS"]["SERIES"][kserie]["CHANNELS"][kchannel] | ||
752 | + for key, val in dico: | ||
753 | + info[key] = val | ||
754 | + return info | ||
755 | + | ||
730 | def get_active_agents(self, unit_name: str) -> list: | 756 | def get_active_agents(self, unit_name: str) -> list: |
731 | """ | 757 | """ |
732 | Return the list of active agents (i.e. agents that have an association with a device) | 758 | Return the list of active agents (i.e. agents that have an association with a device) |
@@ -780,7 +806,7 @@ class OBSConfig: | @@ -780,7 +806,7 @@ class OBSConfig: | ||
780 | 806 | ||
781 | def get_units_name(self) -> list: | 807 | def get_units_name(self) -> list: |
782 | """ | 808 | """ |
783 | - Return list of units names | 809 | + Return list of units names |
784 | 810 | ||
785 | Returns: | 811 | Returns: |
786 | [list]: names of units | 812 | [list]: names of units |
@@ -890,7 +916,7 @@ class OBSConfig: | @@ -890,7 +916,7 @@ class OBSConfig: | ||
890 | 916 | ||
891 | def get_device_information(self, device_name: str) -> dict: | 917 | def get_device_information(self, device_name: str) -> dict: |
892 | """ | 918 | """ |
893 | - Give the dictionary of the attributes of the device | 919 | + Give the dictionary of the attributes of the device |
894 | 920 | ||
895 | Args: | 921 | Args: |
896 | device_name (str): device name | 922 | device_name (str): device name |
@@ -1144,7 +1170,7 @@ class OBSConfig: | @@ -1144,7 +1170,7 @@ class OBSConfig: | ||
1144 | # default with docker should be /home/pyros_user/app | 1170 | # default with docker should be /home/pyros_user/app |
1145 | path_data_root = os.environ['PROJECT_ROOT_PATH'] | 1171 | path_data_root = os.environ['PROJECT_ROOT_PATH'] |
1146 | return path_data_root | 1172 | return path_data_root |
1147 | - | 1173 | + |
1148 | def get_agent_path_data_tree(self, agent_name:str, makedirs: bool=False) -> dict: | 1174 | def get_agent_path_data_tree(self, agent_name:str, makedirs: bool=False) -> dict: |
1149 | """ | 1175 | """ |
1150 | Return a dictionary containing all paths to store data. | 1176 | Return a dictionary containing all paths to store data. |
@@ -1171,11 +1197,38 @@ class OBSConfig: | @@ -1171,11 +1197,38 @@ class OBSConfig: | ||
1171 | for path in data_paths.values(): | 1197 | for path in data_paths.values(): |
1172 | os.makedirs(path, exist_ok = True) | 1198 | os.makedirs(path, exist_ok = True) |
1173 | return data_paths | 1199 | return data_paths |
1174 | - | 1200 | + |
1201 | + def get_image_calibrations(self, unit_name: str) -> dict: | ||
1202 | + """ | ||
1203 | + Return a dictionary containing all strategies of image calibration. | ||
1204 | + | ||
1205 | + Args: | ||
1206 | + agent_name (str): _description_ | ||
1207 | + | ||
1208 | + Returns: | ||
1209 | + All | ||
1210 | + | ||
1211 | + """ | ||
1212 | + path_data_root = self.get_agent_path_data_root(agent_name) | ||
1213 | + data_paths = {} | ||
1214 | + data_paths['data_root'] = path_data_root | ||
1215 | + data_paths['ima_incoming'] = os.path.join(path_data_root,"data/images/incoming") | ||
1216 | + data_paths['ima_processed'] = os.path.join(path_data_root,"data/images/processed") | ||
1217 | + data_paths['ima_tmp'] = os.path.join(path_data_root,"data/images/tmp") | ||
1218 | + data_paths['ima_darks'] = os.path.join(path_data_root,"data/images/darks") | ||
1219 | + data_paths['ima_flats'] = os.path.join(path_data_root,"data/images/flats") | ||
1220 | + data_paths['ima_bias'] = os.path.join(path_data_root,"data/images/bias") | ||
1221 | + data_paths['triton_input'] = os.path.join(path_data_root,"data/triton/input") | ||
1222 | + data_paths['triton_output'] = os.path.join(path_data_root,"data/triton/out") | ||
1223 | + if makedirs == True: | ||
1224 | + for path in data_paths.values(): | ||
1225 | + os.makedirs(path, exist_ok = True) | ||
1226 | + return data_paths | ||
1227 | + | ||
1175 | def get_agent_sst_of_computer(self,computer:str)->str: | 1228 | def get_agent_sst_of_computer(self,computer:str)->str: |
1176 | """ | 1229 | """ |
1177 | Return agent SST config name | 1230 | Return agent SST config name |
1178 | - The agentSST's name in obsconfig must contains AgentSST | 1231 | + The agentSST's name in obsconfig must contains AgentSST |
1179 | 1232 | ||
1180 | Args: | 1233 | Args: |
1181 | computer (str): _description_ | 1234 | computer (str): _description_ |
@@ -1196,7 +1249,7 @@ class OBSConfig: | @@ -1196,7 +1249,7 @@ class OBSConfig: | ||
1196 | if agent.startswith(base_agent_name): | 1249 | if agent.startswith(base_agent_name): |
1197 | return agent | 1250 | return agent |
1198 | except: | 1251 | except: |
1199 | - # do nothing, only goes to in except condition when launching pyros tests because we're simulating obsconfig | 1252 | + # do nothing, only goes to in except condition when launching pyros tests because we're simulating obsconfig |
1200 | pass | 1253 | pass |
1201 | 1254 | ||
1202 | def get_dependencies(self): | 1255 | def get_dependencies(self): |
src/core/pyros_django/observation_manager/AgentImagesCalibrator.py
0 โ 100644
@@ -0,0 +1,333 @@ | @@ -0,0 +1,333 @@ | ||
1 | +#!/usr/bin/env python3 | ||
2 | +# | ||
3 | +# To launch this agent from the root of Pyros: | ||
4 | +# cd /srv/develop/pyros | ||
5 | +# .\PYROS -t start AgentImagesCalibrator -o tnc -fg | ||
6 | +# | ||
7 | +# Edit the file pyros/pyros.py, | ||
8 | +# Add a new entry in the dict AGENT: | ||
9 | +# "AgentImagesCalibrator": "observation_manager", | ||
10 | +# --------------------------------------------------- | ||
11 | + | ||
12 | +import sys | ||
13 | +import time | ||
14 | + | ||
15 | +import os | ||
16 | +pwd = os.environ['PROJECT_ROOT_PATH'] | ||
17 | +if pwd not in sys.path: | ||
18 | + sys.path.append(pwd) | ||
19 | + | ||
20 | +short_paths = ['src', 'src/core/pyros_django'] | ||
21 | +for short_path in short_paths: | ||
22 | + path = os.path.join(pwd, short_path) | ||
23 | + if path not in sys.path: | ||
24 | + sys.path.insert(0, path) | ||
25 | + | ||
26 | +from src.core.pyros_django.agent.Agent import Agent, build_agent, log | ||
27 | + | ||
28 | +# = Specials | ||
29 | +import glob | ||
30 | +import shutil | ||
31 | +import guitastro | ||
32 | + | ||
33 | +class AgentImagesCalibrator(Agent): | ||
34 | + | ||
35 | + # - All possible running states | ||
36 | + RUNNING_NOTHING = 0 | ||
37 | + RUNNING_ONE_IMAGE_PROCESSING = 1 | ||
38 | + RUNNING_COMPUTE_RON_GAIN = 2 | ||
39 | + | ||
40 | + # TODO: Redefine valid timeout | ||
41 | + _AGENT_SPECIFIC_COMMANDS = [ | ||
42 | + ("do_create_test_images_1",60, 0), # self.EXEC_MODE.SEQUENTIAL | ||
43 | + ("do_create_test_images_2",60, 0), # self.EXEC_MODE.THREAD | ||
44 | + ("do_stop_current_processing",60, 0), # self.EXEC_MODE.PROCESS | ||
45 | + ] | ||
46 | + | ||
47 | + # Scenario to be executed | ||
48 | + # "self do_stop_current_processing" | ||
49 | + # AgentCmd.CMD_STATUS_CODE.CMD_EXECUTED | ||
50 | + _TEST_COMMANDS_LIST = [ | ||
51 | + # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status), | ||
52 | + (True, "self do_create_test_images_1", 200, '', Agent.CMD_STATUS.CMD_EXECUTED), | ||
53 | + (True, "self do_exit", 500, "STOPPING", Agent.CMD_STATUS.CMD_EXECUTED), | ||
54 | + ] | ||
55 | + | ||
56 | + """ | ||
57 | + ================================================================= | ||
58 | + Methods running inside main thread | ||
59 | + ================================================================= | ||
60 | + """ | ||
61 | + | ||
62 | + def __init__(self, name:str=None): | ||
63 | + if name is None: | ||
64 | + name = self.__class__.__name__ | ||
65 | + super().__init__() | ||
66 | + | ||
67 | + def _init(self): | ||
68 | + super()._init() | ||
69 | + log.debug("end super init()") | ||
70 | + log.info(f"self.TEST_MODE = {self.TEST_MODE}") | ||
71 | + | ||
72 | + # === Get config infos | ||
73 | + agent_alias = self.name | ||
74 | + log.info(f"agent_alias = {agent_alias}") | ||
75 | + # === Get the config object | ||
76 | + self.config = self._oc['config'] | ||
77 | + # === Get self._path_data_root | ||
78 | + self._path_data_root = self.config.get_agent_path_data_root(agent_alias) | ||
79 | + # === Get self._home of current unit | ||
80 | + self._home = self.config.getHome() | ||
81 | + # === Get self._paths the directories for all data (images). See obsconfig_class.py to know keys | ||
82 | + self._paths = self.config.get_agent_path_data_tree(agent_alias, True) | ||
83 | + # === Get bias strategies | ||
84 | + unit_name = "TNC" | ||
85 | + channel_name = "OpticalChannel_up1" | ||
86 | + category = "BI" | ||
87 | + self_strategy_bias = self.config.get_image_calibrations(unit_name, channel_name, category) | ||
88 | + log.debug(f"self_strategy_bias={self_strategy_bias}") | ||
89 | + | ||
90 | + # === Instanciate an object Ima to make image processing | ||
91 | + self._ima = guitastro.Ima() | ||
92 | + home = guitastro.Home(self._home) | ||
93 | + | ||
94 | + # === Instanciate an object Filenames to manage file names | ||
95 | + self._filename_manager = guitastro.Filenames() | ||
96 | + self._filename_manager.naming("PyROS.1") | ||
97 | + | ||
98 | + # === Set longitude to ima object to generate the night yyyymmdd and subdirectories yyyy/mm/dd | ||
99 | + longitude = home.longitude | ||
100 | + log.info(f"Longitude={longitude}") | ||
101 | + self._ima.longitude(longitude) | ||
102 | + log.info("Init done with success") | ||
103 | + | ||
104 | + # === Status of routine processing | ||
105 | + self._routine_running = self.RUNNING_NOTHING | ||
106 | + log.debug("end init()") | ||
107 | + | ||
108 | + # Note : called by _routine_process() in Agent | ||
109 | + # @override | ||
110 | + def _routine_process_iter_start_body(self): | ||
111 | + log.debug("in routine_process_before_body()") | ||
112 | + | ||
113 | + # Note : called by _routine_process() in Agent | ||
114 | + # @override | ||
115 | + def _routine_process_iter_end_body(self): | ||
116 | + log.debug("in routine_process_after_body()") | ||
117 | + if self._routine_running == self.RUNNING_NOTHING: | ||
118 | + # Get files to process | ||
119 | + fitsfiles = self.glob_images_to_process() | ||
120 | + n = len(fitsfiles) | ||
121 | + log.info(f"There are {n} image{self._plural(n)} to process") | ||
122 | + if n > 0: | ||
123 | + # - We select the oldest image | ||
124 | + fitsfile = fitsfiles[0] | ||
125 | + log.info(f"Process the file {fitsfile}") | ||
126 | + # - Thread TODO | ||
127 | + self._routine_running = self.RUNNING_ONE_IMAGE_PROCESSING | ||
128 | + self.process_one_image(fitsfile) | ||
129 | + | ||
130 | + """ | ||
131 | + ================================================================= | ||
132 | + Methods of specific commands | ||
133 | + ================================================================= | ||
134 | + """ | ||
135 | + | ||
136 | + def do_stop_current_processing(self): | ||
137 | + pass | ||
138 | + | ||
139 | + def do_create_test_images_1(self): | ||
140 | + self._create_test_images_1() | ||
141 | + | ||
142 | + def do_create_test_images_2(self): | ||
143 | + self._create_test_images_2() | ||
144 | + | ||
145 | + """ | ||
146 | + ================================================================= | ||
147 | + Methods called by commands or routine. Overload these methods | ||
148 | + ================================================================= | ||
149 | + """ | ||
150 | + | ||
151 | + def glob_images_to_process(self): | ||
152 | + | ||
153 | + # - glob the incoming directory: | ||
154 | + fitsfiles = glob.glob(f"{self._paths['ima_incoming']}/BI_*.fit") | ||
155 | + # - Please sort list of files in increasing dates (TODO) | ||
156 | + return fitsfiles | ||
157 | + | ||
158 | + def bias_correction(self): | ||
159 | + | ||
160 | + # - Search the bias | ||
161 | + path_bias = os.path.join( self._paths['ima_bias'], self._date_night ) | ||
162 | + fitsbiasfiles = glob.glob(f"{path_bias}/*.fit") | ||
163 | + log.info(f"fitsbiasfiles = {fitsbiasfiles}") | ||
164 | + if len(fitsbiasfiles) > 0: | ||
165 | + | ||
166 | + # - Select the bias | ||
167 | + pass | ||
168 | + | ||
169 | + def dark_correction(self): | ||
170 | + | ||
171 | + # - Search the dark | ||
172 | + path_darks = os.path.join( self._paths['ima_darks'], self._date_night ) | ||
173 | + fitsdarkfiles = glob.glob(f"{path_darks}/*.fit") | ||
174 | + log.info(f"fitsdarkfiles = {fitsdarkfiles}") | ||
175 | + if len(fitsdarkfiles) > 0: | ||
176 | + | ||
177 | + # - Select two darks and compute the therm using exposure | ||
178 | + # - Correction of dark | ||
179 | + pass | ||
180 | + | ||
181 | + def flat_correction(self): | ||
182 | + | ||
183 | + # - Search the flat | ||
184 | + path_flats = os.path.join( self._paths['ima_flats'], self._date_night ) | ||
185 | + fitsflatfiles = glob.glob(f"{path_flats}/*.fit") | ||
186 | + log.info(f"fitsflatfiles = {fitsflatfiles}") | ||
187 | + if len(fitsflatfiles) > 0: | ||
188 | + | ||
189 | + # - Select the flat (with the filter) | ||
190 | + # - Correction of flat | ||
191 | + pass | ||
192 | + | ||
193 | + def inversion_correction(self): | ||
194 | + pass | ||
195 | + | ||
196 | + def cosmetic_correction(self): | ||
197 | + pass | ||
198 | + | ||
199 | + def wcs_calibration(self): | ||
200 | + return 0 | ||
201 | + | ||
202 | + def process_one_image(self, fitsfile: str): | ||
203 | + """This is the general algorithm of processing | ||
204 | + | ||
205 | + The processing consists to make corrections of dark, flat, inversions, cosmetic | ||
206 | + and perform WCS calibration. | ||
207 | + | ||
208 | + Args: | ||
209 | + fitsfile: The file of the FITS file to process. | ||
210 | + | ||
211 | + """ | ||
212 | + | ||
213 | + # - Load file in memory | ||
214 | + log.info("Load the file in memory") | ||
215 | + #self.set_infos("Load the file in memory") | ||
216 | + f = self._ima.genename(self._ima.load(fitsfile)) | ||
217 | + # log.info(f"f={f}") | ||
218 | + | ||
219 | + # - Save as tmp | ||
220 | + self._ima.path(self._paths['ima_tmp']) | ||
221 | + log.info("Save the temporary file as tmp name") | ||
222 | + self._ima.save("tmp") | ||
223 | + | ||
224 | + # - Load tmp and get infos | ||
225 | + self._ima.load("tmp") | ||
226 | + date_obs = self._ima.getkwd("DATE-OBS") | ||
227 | + self._date_night = self._ima.get_night(date_obs) | ||
228 | + log.info(f"Date_obs = {date_obs}") | ||
229 | + log.info(f"Night = {self._date_night}") | ||
230 | + exposure = self._ima.getkwd("EXPOSURE") | ||
231 | + log.info(f"Exposure = {exposure}") | ||
232 | + | ||
233 | + # - Bias correction | ||
234 | + self.bias_correction() | ||
235 | + | ||
236 | + # - Dark correction | ||
237 | + self.dark_correction() | ||
238 | + | ||
239 | + # - Flat correction | ||
240 | + self.flat_correction() | ||
241 | + | ||
242 | + # - Save tmp corrected by dark and flat | ||
243 | + self._ima.path(self._paths['ima_tmp']) | ||
244 | + self._ima.save("tmp") | ||
245 | + | ||
246 | + # - Inversion of mirrors or mirorxy | ||
247 | + self.inversion_correction() | ||
248 | + | ||
249 | + # - Cosmetic correction | ||
250 | + self.cosmetic_correction() | ||
251 | + | ||
252 | + # - WCS calibration | ||
253 | + nmatched = self.wcs_calibration() | ||
254 | + | ||
255 | + # - Prepare the output file name | ||
256 | + log.info("Decode the filename") | ||
257 | + fgen_in = f['genename'] + f['sep'] + f['indexes'][0] + f['suffix'] | ||
258 | + fext_in = f['file_extension'] | ||
259 | + fext_out = ".fits" | ||
260 | + | ||
261 | + # - Save in processed | ||
262 | + yyyy = self._date_night[0:4] | ||
263 | + mm = self._date_night[4:6] | ||
264 | + dd = self._date_night[6:8] | ||
265 | + path_processed = os.path.join( self._paths['ima_processed'], yyyy, mm, dd ) | ||
266 | + self._ima.path(path_processed) | ||
267 | + fname_out = fgen_in + fext_out | ||
268 | + fname = self._ima.save(fname_out) | ||
269 | + log.info(f"Save the processed image {fname}") | ||
270 | + | ||
271 | + # - Delete the file in incoming directory | ||
272 | + os.remove(fitsfile) | ||
273 | + log.info(f"Delete the raw image {fitsfile}") | ||
274 | + | ||
275 | + # - Update the running state | ||
276 | + self._routine_running = self.RUNNING_NOTHING | ||
277 | + | ||
278 | + time.sleep(5) | ||
279 | + print("\n ...End of image calibration\n") | ||
280 | + | ||
281 | + """ | ||
282 | + ================================================================= | ||
283 | + Internal methods | ||
284 | + ================================================================= | ||
285 | + """ | ||
286 | + | ||
287 | + def _create_test_images_1(self): | ||
288 | + try: | ||
289 | + # === Define an image to test the processing and copy it in incoming directory | ||
290 | + self._file_ima_test = os.path.join(self._path_data_root,"vendor/guitastro/tests/data/m57.fit") | ||
291 | + file_in = self._file_ima_test | ||
292 | + file_out = f"{self._paths['ima_incoming']}/m57.fit" | ||
293 | + shutil.copyfile(file_in, file_out) | ||
294 | + self._filename_manager.naming("") | ||
295 | + except: | ||
296 | + raise | ||
297 | + | ||
298 | + def _create_test_images_2(self): | ||
299 | + try: | ||
300 | + self._ima.etc.camera("Kepler 4040") | ||
301 | + self._ima.etc.optics("Takahashi_180ED") | ||
302 | + self._ima.etc.params("msky",18) | ||
303 | + ra = 132.84583 | ||
304 | + dec = 11.81333 | ||
305 | + at = self._ima.simulation("GAIA", "PHOTOM", shutter_mode="closed", t=50) | ||
306 | + file_out = os.path.join(self._paths['ima_tmp'], "m67.ecsv") | ||
307 | + print(f"STEP TOTO 1 = {at}") | ||
308 | + at.t.write(file_out, format='astrotable', overwrite=True) | ||
309 | + print(f"STEP TOTO 2") | ||
310 | + date_obs = self.getkwd("DATE-OBS") | ||
311 | + except: | ||
312 | + raise | ||
313 | + | ||
314 | + def _plural(self, n: int) -> str: | ||
315 | + """Return "s" if n>1 for plurals. | ||
316 | + | ||
317 | + Args: | ||
318 | + n: Number of entities | ||
319 | + | ||
320 | + Returns: | ||
321 | + The string "s" or "" | ||
322 | + """ | ||
323 | + if n > 1: | ||
324 | + s = "s" | ||
325 | + else: | ||
326 | + s = "" | ||
327 | + return s | ||
328 | + | ||
329 | +if __name__ == "__main__": | ||
330 | + | ||
331 | + agent = build_agent(AgentImagesCalibrator) | ||
332 | + print(agent) | ||
333 | + agent.run() |
src/core/pyros_django/observation_manager/AgentImagesProcessor.py
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | # | 2 | # |
3 | # To launch this agent from the root of Pyros: | 3 | # To launch this agent from the root of Pyros: |
4 | # cd /srv/develop/pyros | 4 | # cd /srv/develop/pyros |
5 | -# .\PYROS -t start agentImagesProcessor -o tnc -fg | 5 | +# .\PYROS -t start AgentImagesProcessor -o tnc -fg |
6 | # | 6 | # |
7 | # --------------------------------------------------- | 7 | # --------------------------------------------------- |
8 | 8 |