Commit b6ff102c318f66fe6287aafd7e5cac758eaa7a1a

Authored by Etienne Pallier
2 parents a56e6e0e 683fc05b
Exists in dev

Merge branch 'dev' of https://gitlab.irap.omp.eu/pyros-irap/pyros into dev

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