Commit b6ff102c318f66fe6287aafd7e5cac758eaa7a1a
Exists in
dev
Merge branch 'dev' of https://gitlab.irap.omp.eu/pyros-irap/pyros into dev
Showing
5 changed files
with
110 additions
and
55 deletions
Show diff stats
src/core/pyros_django/bdf_process/A_BDFProcessor.py
1 | #!/usr/bin/env python3 | 1 | #!/usr/bin/env python3 |
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 | ||
5 | -# .\PYROS -t start AgentImagesCalibrator -o tnc -fg | ||
6 | # | 4 | # |
7 | -# Edit the file pyros/pyros.py, | ||
8 | -# Add a new entry in the dict AGENT: | ||
9 | -# "AgentImagesCalibrator": "observation_manager", | 5 | +# Linux console: |
6 | +# cd /srv/develop/pyros/docker | ||
7 | +# ./PYROS_DOCKER_START.sh | ||
8 | +# | ||
9 | +# Launch from Power Shell: | ||
10 | +# To go from docker to Powershell: pyros_user@ORION:~/app$ exit (or Ctrl+d) | ||
11 | +# Prompt is now PS ...> | ||
12 | +# cd \srv\develop\pyros | ||
13 | +# .\PYROS -t new-start -o tnc -fg -a A_BDFProcessor_tnc_up1_akz | ||
14 | +# | ||
15 | +# Launch from docker: | ||
16 | +# To go from Powershell to docker: PS ...> .\PYROS_DOCKER_SHELL | ||
17 | +# Prompt is now pyros_user@ORION:~/app$ | ||
18 | +# ./PYROS -t new-start -o tnc -fg -a A_BDFProcessor_tnc_up1_akz | ||
19 | +# | ||
20 | +# To use debug | ||
21 | +# ./PYROS -d -t new-start -o tnc -fg -a A_BDFProcessor | ||
22 | +# | ||
23 | +# ./PYROS -d -t start -o tnc -fg A_BDFProcessor | ||
10 | # --------------------------------------------------- | 24 | # --------------------------------------------------- |
11 | 25 | ||
12 | import sys | 26 | import sys |
13 | import time | 27 | import time |
14 | - | 28 | +import argparse |
15 | import os | 29 | import os |
30 | +import pickle | ||
31 | +import socket | ||
16 | pwd = os.environ['PROJECT_ROOT_PATH'] | 32 | pwd = os.environ['PROJECT_ROOT_PATH'] |
17 | if pwd not in sys.path: | 33 | if pwd not in sys.path: |
18 | sys.path.append(pwd) | 34 | sys.path.append(pwd) |
@@ -23,8 +39,8 @@ for short_path in short_paths: | @@ -23,8 +39,8 @@ for short_path in short_paths: | ||
23 | if path not in sys.path: | 39 | if path not in sys.path: |
24 | sys.path.insert(0, path) | 40 | sys.path.insert(0, path) |
25 | 41 | ||
26 | -from src.core.pyros_django.majordome.agent.Agent import Agent, build_agent, log | ||
27 | - | 42 | +from src.core.pyros_django.majordome.agent.Agent import Agent, build_agent, log, parse_args |
43 | +from seq_submit.models import Sequence, Album, Plan, Image | ||
28 | # = Specials | 44 | # = Specials |
29 | import glob | 45 | import glob |
30 | import shutil | 46 | import shutil |
@@ -40,74 +56,88 @@ class A_BDFProcessor(Agent): | @@ -40,74 +56,88 @@ class A_BDFProcessor(Agent): | ||
40 | # TODO: Redefine valid timeout | 56 | # TODO: Redefine valid timeout |
41 | _AGENT_SPECIFIC_COMMANDS = { | 57 | _AGENT_SPECIFIC_COMMANDS = { |
42 | # Format : “cmd_name” : (timeout, exec_mode) | 58 | # Format : “cmd_name” : (timeout, exec_mode) |
43 | - | 59 | + |
44 | "do_create_test_images_1" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), | 60 | "do_create_test_images_1" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), |
45 | "do_create_test_images_2" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), | 61 | "do_create_test_images_2" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), |
46 | "do_stop_current_processing" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), | 62 | "do_stop_current_processing" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), |
47 | } | 63 | } |
48 | 64 | ||
49 | - | ||
50 | - | ||
51 | - | ||
52 | - # Scenario to be executed | 65 | + # Test scenario to be executed (option -t) |
53 | # "self do_stop_current_processing" | 66 | # "self do_stop_current_processing" |
54 | # AgentCmd.CMD_STATUS_CODE.CMD_EXECUTED | 67 | # AgentCmd.CMD_STATUS_CODE.CMD_EXECUTED |
55 | _TEST_COMMANDS_LIST = [ | 68 | _TEST_COMMANDS_LIST = [ |
56 | # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status), | 69 | # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status), |
57 | - (True, "self do_create_test_images_1", 200, '', Agent.CMD_STATUS.CMD_EXECUTED), | ||
58 | - (True, "self do_exit", 500, "STOPPING", Agent.CMD_STATUS.CMD_EXECUTED), | 70 | + (True, "self do_create_test_images_1", 500, "", Agent.CMD_STATUS.CMD_EXECUTED), |
71 | + (True, "self do_stop asap", 500, "STOPPING", Agent.CMD_STATUS.CMD_EXECUTED), | ||
59 | ] | 72 | ] |
60 | - | 73 | + |
61 | """ | 74 | """ |
62 | ================================================================= | 75 | ================================================================= |
63 | Methods running inside main thread | 76 | Methods running inside main thread |
64 | ================================================================= | 77 | ================================================================= |
65 | """ | 78 | """ |
66 | 79 | ||
67 | - def __init__(self, name:str=None): | 80 | + def __init__(self, name:str=None,simulated_computer=None): |
68 | if name is None: | 81 | if name is None: |
69 | name = self.__class__.__name__ | 82 | name = self.__class__.__name__ |
70 | - super().__init__() | 83 | + super().__init__(simulated_computer=simulated_computer) |
71 | 84 | ||
72 | def _init(self): | 85 | def _init(self): |
73 | super()._init() | 86 | super()._init() |
74 | - log.debug("end super init()") | ||
75 | - log.info(f"self.TEST_MODE = {self.TEST_MODE}") | 87 | + log.debug("End super init()") |
88 | + log.info(f"self.TEST_MODE = {self.TEST_MODE}") # is_in_test_mode() | ||
89 | + log.info(f"self.is_in_test_mode() = {self.is_in_test_mode()}") # is_in_test_mode() | ||
76 | 90 | ||
77 | - # === Get config infos | ||
78 | - agent_alias = self.name | ||
79 | - log.info(f"agent_alias = {agent_alias}") | ||
80 | # === Get the config object | 91 | # === Get the config object |
81 | self.config = self._oc['config'] | 92 | self.config = self._oc['config'] |
82 | - # === Get self._path_data_root | ||
83 | - self._path_data_root = self.config.get_agent_path_data_root(agent_alias) | ||
84 | - # === Get self._home of current unit | 93 | + self.pconfig = self._oc['pyros_config'] |
94 | + | ||
95 | + # === Get agent_alias | ||
96 | + hostname = socket.gethostname() | ||
97 | + log.info(f"{hostname=}") | ||
98 | + log.info(f"{self.name=}") | ||
99 | + agent_alias = self.config.get_agent_real_name(self.name, hostname) | ||
100 | + log.info(f"{agent_alias=}") | ||
101 | + | ||
102 | + # === Get self._home (str) of current unit | ||
85 | self._home = self.config.getHome() | 103 | self._home = self.config.getHome() |
86 | - # === Get self._paths the directories for all data (images). See obsconfig_class.py to know keys | ||
87 | - self._paths = self.config.get_agent_path_data_tree(agent_alias, True) | ||
88 | - # === Get bias strategies | ||
89 | - unit_name = "TNC" | ||
90 | - channel_name = "OpticalChannel_up1" | ||
91 | - category = "BI" | ||
92 | - self_strategy_bias = self.config.get_image_calibrations(unit_name, channel_name, category) | ||
93 | - log.debug(f"self_strategy_bias={self_strategy_bias}") | ||
94 | 104 | ||
95 | - # === Instanciate an object Ima to make image processing | ||
96 | - self._ima = guitastro.Ima() | 105 | + # === Get home (Home object) of current unit |
97 | home = guitastro.Home(self._home) | 106 | home = guitastro.Home(self._home) |
98 | 107 | ||
99 | - # === Instanciate an object Filenames to manage file names | ||
100 | - self._filename_manager = guitastro.FileNames() | ||
101 | - self._filename_manager.naming("PyROS.1") | 108 | + # === Get the channel of agent |
109 | + channel = self.config.get_channel_of_agent(agent_alias) | ||
110 | + if channel == None: | ||
111 | + raise Exception(f"{agent_alias} has no channel file contexts {channel=}") | ||
112 | + #log.info(f"{channel=}") | ||
113 | + self._channel = channel | ||
102 | 114 | ||
103 | - # === Set longitude to ima object to generate the night yyyymmdd and subdirectories yyyy/mm/dd | ||
104 | - longitude = home.longitude | ||
105 | - log.info(f"Longitude={longitude}") | ||
106 | - self._ima.longitude(longitude) | ||
107 | - log.info("Init done with success") | 115 | + # === Get all file contexts from the channel config |
116 | + self._fn = channel['fn_contexts'] | ||
117 | + | ||
118 | + # === Get all file contexts from pyros config | ||
119 | + # Shouldn't be used in channel's agent (self.config.fn are general fcontext) | ||
120 | + #self._fn = self.config.fn | ||
121 | + log.info(f"=== List of file name contexts available for the unit") | ||
122 | + self.check_contexts(False) | ||
123 | + log.info(f"{self._fn.longitude=}") | ||
124 | + | ||
125 | + # === Instanciate an object Ima to make image processing | ||
126 | + self._ima = guitastro.Ima() | ||
108 | 127 | ||
128 | + # === Set longitude to ima object to generate the night yyyymmdd and subdirectories yyyy/mm/dd | ||
129 | + self._ima.longitude = self._fn.longitude | ||
130 | + | ||
131 | + # === Copy and update the channel file contexts into the Ima object | ||
132 | + self._ima.fcontext_replace(channel['fn_contexts']) | ||
133 | + log.info(f"=== List of file name contexts available for the channel {channel['name']} ({channel['symbol']})") | ||
134 | + for fcname in self._ima.fcontexts: | ||
135 | + self._ima.fcontext = fcname | ||
136 | + log.info(f"{fcname} : {self._ima.fdescription} {self._ima.rootdir}/[{self._ima.pathing()}]/[{self._ima.naming()}]{self._ima.extension}") | ||
137 | + | ||
109 | # === Status of routine processing | 138 | # === Status of routine processing |
110 | self._routine_running = self.RUNNING_NOTHING | 139 | self._routine_running = self.RUNNING_NOTHING |
140 | + log.info("Init done with success") | ||
111 | log.debug("end init()") | 141 | log.debug("end init()") |
112 | 142 | ||
113 | # Note : called by _routine_process() in Agent | 143 | # Note : called by _routine_process() in Agent |
@@ -142,10 +172,20 @@ class A_BDFProcessor(Agent): | @@ -142,10 +172,20 @@ class A_BDFProcessor(Agent): | ||
142 | pass | 172 | pass |
143 | 173 | ||
144 | def do_create_test_images_1(self): | 174 | def do_create_test_images_1(self): |
145 | - self._create_test_images_1() | 175 | + """Create images to make tests. |
176 | + """ | ||
177 | + try: | ||
178 | + self._create_test_images_1() | ||
179 | + except Exception as e: | ||
180 | + self.dprint(f"ERROR {e}") | ||
146 | 181 | ||
147 | def do_create_test_images_2(self): | 182 | def do_create_test_images_2(self): |
148 | - self._create_test_images_2() | 183 | + """Create images to make tests. |
184 | + """ | ||
185 | + try: | ||
186 | + self._create_test_images_2() | ||
187 | + except Exception as e: | ||
188 | + self.dprint(f"ERROR {e}") | ||
149 | 189 | ||
150 | """ | 190 | """ |
151 | ================================================================= | 191 | ================================================================= |
src/core/pyros_django/img_process/A_ImgProcessor.py
@@ -17,6 +17,10 @@ | @@ -17,6 +17,10 @@ | ||
17 | # Prompt is now pyros_user@ORION:~/app$ | 17 | # Prompt is now pyros_user@ORION:~/app$ |
18 | # ./PYROS -t new-start -o tnc -fg -a A_ImgProcessor_tnc_up1_akz | 18 | # ./PYROS -t new-start -o tnc -fg -a A_ImgProcessor_tnc_up1_akz |
19 | # | 19 | # |
20 | +# To use debug | ||
21 | +# ./PYROS -d -t new-start -o tnc -fg -a A_ImgProcessor | ||
22 | +# | ||
23 | +# ./PYROS -d -t start -o tnc -fg A_ImgProcessor | ||
20 | # --------------------------------------------------- | 24 | # --------------------------------------------------- |
21 | 25 | ||
22 | import sys | 26 | import sys |
src/core/pyros_django/majordome/agent/Agent.py
@@ -3572,6 +3572,10 @@ class Agent: | @@ -3572,6 +3572,10 @@ class Agent: | ||
3572 | targets = ['sun', 'moon'] | 3572 | targets = ['sun', 'moon'] |
3573 | jd = jd1 + 0.1 | 3573 | jd = jd1 + 0.1 |
3574 | total1 = 0 | 3574 | total1 = 0 |
3575 | + | ||
3576 | + d_prev = 0 | ||
3577 | + d_cur = 0 | ||
3578 | + d_total = 0 | ||
3575 | night_info = {} | 3579 | night_info = {} |
3576 | while jd < jd2: | 3580 | while jd < jd2: |
3577 | night = self._oc['config'].fn.date2night(jd) | 3581 | night = self._oc['config'].fn.date2night(jd) |
@@ -3580,16 +3584,18 @@ class Agent: | @@ -3580,16 +3584,18 @@ class Agent: | ||
3580 | ephem = self.ephem_target2night(target, jd) | 3584 | ephem = self.ephem_target2night(target, jd) |
3581 | if target == "sun": | 3585 | if target == "sun": |
3582 | ks = np.where(ephem['alt'] < self._duskelev) | 3586 | ks = np.where(ephem['alt'] < self._duskelev) |
3583 | - total_night = len(ks[0]) | ||
3584 | - total2 = total1 + total_night | ||
3585 | - sec1 = ks[0][0] | ||
3586 | - sec2 = ks[0][-1] | ||
3587 | - night_info[night] = [int(total1), int(total2), int(total_night), sec1, sec2] | ||
3588 | - total1 = total2 | 3587 | + d_prev = d_prev + d_cur |
3588 | + d_cur = len(ks[0]) | ||
3589 | + night_info[night] = [0, d_prev, d_cur, 0] | ||
3589 | jd += 1 | 3590 | jd += 1 |
3590 | - night_info['total'] = [0, int(total2), int(total2), -1, -1] | ||
3591 | - self.dprint(f"Write {filename=}") | ||
3592 | - pickle.dump(night_info, open(filename, "wb")) | 3591 | + d_total = d_prev + d_cur |
3592 | + for key, val in night_info.items(): | ||
3593 | + val[0] = d_total | ||
3594 | + val[-1] = d_total - val[-2] | ||
3595 | + # --- update db TODO | ||
3596 | + | ||
3597 | + #log.info(f"Write {filename=}") | ||
3598 | + #pickle.dump(night_info, open(filename, "wb")) | ||
3593 | return night_info | 3599 | return night_info |
3594 | 3600 | ||
3595 | """ | 3601 | """ |
src/core/pyros_django/scheduling/A_Scheduler.py
@@ -159,6 +159,8 @@ class A_Scheduler(Agent): | @@ -159,6 +159,8 @@ class A_Scheduler(Agent): | ||
159 | 159 | ||
160 | def do_create_seq_1(self, nb_seq:int): | 160 | def do_create_seq_1(self, nb_seq:int): |
161 | """Create sequences to debug | 161 | """Create sequences to debug |
162 | + :raises ExceptionType: Some multi-line | ||
163 | + exception description. | ||
162 | """ | 164 | """ |
163 | try: | 165 | try: |
164 | self._create_seq_1(nb_seq) | 166 | self._create_seq_1(nb_seq) |
@@ -335,6 +337,8 @@ class A_Scheduler(Agent): | @@ -335,6 +337,8 @@ class A_Scheduler(Agent): | ||
335 | self.dprint(f" {scientific_program_id=} range to start={len(kobss)}") | 337 | self.dprint(f" {scientific_program_id=} range to start={len(kobss)}") |
336 | if scientific_program_id not in scientific_program_ids: | 338 | if scientific_program_id not in scientific_program_ids: |
337 | scientific_program_ids.append(scientific_program_id) | 339 | scientific_program_ids.append(scientific_program_id) |
340 | + # --- TODO | ||
341 | + # update_db_quota_sequence( id_period, night_id, d_total=sequence_info['duration'] ) | ||
338 | else: | 342 | else: |
339 | sequence_info['error'] = f"File {ephfile} not exists" | 343 | sequence_info['error'] = f"File {ephfile} not exists" |
340 | sequence_infos.append(sequence_info) | 344 | sequence_infos.append(sequence_info) |
src/core/pyros_django/scp_mgmt/A_SCP_Manager.py
@@ -244,6 +244,7 @@ class A_SCP_Manager(Agent): | @@ -244,6 +244,7 @@ class A_SCP_Manager(Agent): | ||
244 | yield start_date + timedelta(n) | 244 | yield start_date + timedelta(n) |
245 | 245 | ||
246 | def do_generate_ephem_moon_and_sun_for_period(self, period_id:int): | 246 | def do_generate_ephem_moon_and_sun_for_period(self, period_id:int): |
247 | + # Obsolete TODO | ||
247 | period = Period.objects.get(id=period_id) | 248 | period = Period.objects.get(id=period_id) |
248 | period_start_date = period.start_date | 249 | period_start_date = period.start_date |
249 | period_end_date = period.end_date | 250 | period_end_date = period.end_date |