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 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
... ...