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 | 1 | #!/usr/bin/env python3 |
2 | 2 | # |
3 | 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 | 26 | import sys |
13 | 27 | import time |
14 | - | |
28 | +import argparse | |
15 | 29 | import os |
30 | +import pickle | |
31 | +import socket | |
16 | 32 | pwd = os.environ['PROJECT_ROOT_PATH'] |
17 | 33 | if pwd not in sys.path: |
18 | 34 | sys.path.append(pwd) |
... | ... | @@ -23,8 +39,8 @@ for short_path in short_paths: |
23 | 39 | if path not in sys.path: |
24 | 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 | 44 | # = Specials |
29 | 45 | import glob |
30 | 46 | import shutil |
... | ... | @@ -40,74 +56,88 @@ class A_BDFProcessor(Agent): |
40 | 56 | # TODO: Redefine valid timeout |
41 | 57 | _AGENT_SPECIFIC_COMMANDS = { |
42 | 58 | # Format : “cmd_name” : (timeout, exec_mode) |
43 | - | |
59 | + | |
44 | 60 | "do_create_test_images_1" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), |
45 | 61 | "do_create_test_images_2" : (60, Agent.EXEC_MODE.SEQUENTIAL, ''), |
46 | 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 | 66 | # "self do_stop_current_processing" |
54 | 67 | # AgentCmd.CMD_STATUS_CODE.CMD_EXECUTED |
55 | 68 | _TEST_COMMANDS_LIST = [ |
56 | 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 | 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 | 81 | if name is None: |
69 | 82 | name = self.__class__.__name__ |
70 | - super().__init__() | |
83 | + super().__init__(simulated_computer=simulated_computer) | |
71 | 84 | |
72 | 85 | def _init(self): |
73 | 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 | 91 | # === Get the config object |
81 | 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 | 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 | 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 | 138 | # === Status of routine processing |
110 | 139 | self._routine_running = self.RUNNING_NOTHING |
140 | + log.info("Init done with success") | |
111 | 141 | log.debug("end init()") |
112 | 142 | |
113 | 143 | # Note : called by _routine_process() in Agent |
... | ... | @@ -142,10 +172,20 @@ class A_BDFProcessor(Agent): |
142 | 172 | pass |
143 | 173 | |
144 | 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 | 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 | 17 | # Prompt is now pyros_user@ORION:~/app$ |
18 | 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 | 26 | import sys | ... | ... |
src/core/pyros_django/majordome/agent/Agent.py
... | ... | @@ -3572,6 +3572,10 @@ class Agent: |
3572 | 3572 | targets = ['sun', 'moon'] |
3573 | 3573 | jd = jd1 + 0.1 |
3574 | 3574 | total1 = 0 |
3575 | + | |
3576 | + d_prev = 0 | |
3577 | + d_cur = 0 | |
3578 | + d_total = 0 | |
3575 | 3579 | night_info = {} |
3576 | 3580 | while jd < jd2: |
3577 | 3581 | night = self._oc['config'].fn.date2night(jd) |
... | ... | @@ -3580,16 +3584,18 @@ class Agent: |
3580 | 3584 | ephem = self.ephem_target2night(target, jd) |
3581 | 3585 | if target == "sun": |
3582 | 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 | 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 | 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 | 159 | |
160 | 160 | def do_create_seq_1(self, nb_seq:int): |
161 | 161 | """Create sequences to debug |
162 | + :raises ExceptionType: Some multi-line | |
163 | + exception description. | |
162 | 164 | """ |
163 | 165 | try: |
164 | 166 | self._create_seq_1(nb_seq) |
... | ... | @@ -335,6 +337,8 @@ class A_Scheduler(Agent): |
335 | 337 | self.dprint(f" {scientific_program_id=} range to start={len(kobss)}") |
336 | 338 | if scientific_program_id not in scientific_program_ids: |
337 | 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 | 342 | else: |
339 | 343 | sequence_info['error'] = f"File {ephfile} not exists" |
340 | 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 | 244 | yield start_date + timedelta(n) |
245 | 245 | |
246 | 246 | def do_generate_ephem_moon_and_sun_for_period(self, period_id:int): |
247 | + # Obsolete TODO | |
247 | 248 | period = Period.objects.get(id=period_id) |
248 | 249 | period_start_date = period.start_date |
249 | 250 | period_end_date = period.end_date | ... | ... |