Commit 24be3797cbe226c044521f11437eee97a3df0ba5

Authored by pyros_astroguita
1 parent fafd18bd
Exists in dev

A_Scheduler real sequence for test with file template

src/core/pyros_django/scheduling/A_Scheduler.py
@@ -5,6 +5,9 @@ @@ -5,6 +5,9 @@
5 # Linux console: 5 # Linux console:
6 # cd /srv/develop/pyros/docker 6 # cd /srv/develop/pyros/docker
7 # ./PYROS_DOCKER_START.sh 7 # ./PYROS_DOCKER_START.sh
  8 +# ./PYROS_RUN_WEBSERVER_ONLY -o tnc -fg
  9 +# cd ..
  10 +# ./PYROS start -o tnc -fg -a A_Scheduler
8 # 11 #
9 # Launch from Power Shell: 12 # Launch from Power Shell:
10 # To go from docker to Powershell: pyros_user@ORION:~/app$ exit (or Ctrl+d) 13 # To go from docker to Powershell: pyros_user@ORION:~/app$ exit (or Ctrl+d)
@@ -29,6 +32,7 @@ import argparse @@ -29,6 +32,7 @@ import argparse
29 import os 32 import os
30 import pickle 33 import pickle
31 import socket 34 import socket
  35 +import yaml
32 36
33 pwd = os.environ['PROJECT_ROOT_PATH'] 37 pwd = os.environ['PROJECT_ROOT_PATH']
34 if pwd not in sys.path: 38 if pwd not in sys.path:
@@ -44,6 +48,7 @@ for short_path in short_paths: @@ -44,6 +48,7 @@ for short_path in short_paths:
44 from majordome.agent.Agent import Agent, build_agent, log, parse_args 48 from majordome.agent.Agent import Agent, build_agent, log, parse_args
45 from seq_submit.models import Sequence 49 from seq_submit.models import Sequence
46 from user_mgmt.models import Period, ScientificProgram, SP_Period 50 from user_mgmt.models import Period, ScientificProgram, SP_Period
  51 +from scp_mgmt.models import Quota
47 from scheduling.models import PredictiveSchedule, EffectiveSchedule 52 from scheduling.models import PredictiveSchedule, EffectiveSchedule
48 # = Specials 53 # = Specials
49 import glob 54 import glob
@@ -54,6 +59,8 @@ from decimal import Decimal @@ -54,6 +59,8 @@ from decimal import Decimal
54 import zoneinfo 59 import zoneinfo
55 import numpy as np 60 import numpy as np
56 61
  62 +from pyros_api import PyrosAPI
  63 +
57 class A_Scheduler(Agent): 64 class A_Scheduler(Agent):
58 65
59 DPRINT = True 66 DPRINT = True
@@ -223,7 +230,7 @@ class A_Scheduler(Agent): @@ -223,7 +230,7 @@ class A_Scheduler(Agent):
223 """ 230 """
224 231
225 232
226 - def update_db_quota_sequence(sequence_id, quota_attributes): 233 + def update_db_quota_sequence(self, sequence_id, quota_attributes):
227 sequence = Sequence.objects.get(id=sequence_id) 234 sequence = Sequence.objects.get(id=sequence_id)
228 new_quota = Quota() 235 new_quota = Quota()
229 new_quota.set_attributes_and_save(quota_attributes) 236 new_quota.set_attributes_and_save(quota_attributes)
@@ -249,13 +256,14 @@ class A_Scheduler(Agent): @@ -249,13 +256,14 @@ class A_Scheduler(Agent):
249 # --- Get the night 256 # --- Get the night
250 night = info['night'] 257 night = info['night']
251 # --- Get ephemeris informations of the night and initialize quotas 258 # --- Get ephemeris informations of the night and initialize quotas
252 - night_info = self.update_sun_moon_ephems()  
253 - quota_total_period = night_info['total'][1]  
254 - quota_total_night_start = night_info[night][0]  
255 - quota_total_night_end = night_info[night][1]  
256 - self.dprint(f"{quota_total_period=}")  
257 - self.dprint(f"{quota_total_night_start=}")  
258 - self.dprint(f"{quota_total_night_end=}") 259 + self.update_sun_moon_ephems()
  260 +
  261 + # Get quota for night
  262 +
  263 + oquota = Quota.objects.get(id_period=info["operiod"].id, night_id=info["night"])
  264 +
  265 +
  266 +
259 # --- Build the wildcard to list the sequences 267 # --- Build the wildcard to list the sequences
260 wildcard = os.path.join(rootdir, subdir, "*.p") 268 wildcard = os.path.join(rootdir, subdir, "*.p")
261 self.dprint(f"{wildcard=}") 269 self.dprint(f"{wildcard=}")
@@ -329,6 +337,7 @@ class A_Scheduler(Agent): @@ -329,6 +337,7 @@ class A_Scheduler(Agent):
329 eph_info = pickle.load(open(ephfile,"rb")) 337 eph_info = pickle.load(open(ephfile,"rb"))
330 #print("="*20 + "\n" + f"{eph_info=}") 338 #print("="*20 + "\n" + f"{eph_info=}")
331 # --- 339 # ---
  340 + self._fn.fcontext = "pyros_seq"
332 param = self._fn.naming_get(seqfile) 341 param = self._fn.naming_get(seqfile)
333 sequence_info['id'] = int(param['id_seq']) 342 sequence_info['id'] = int(param['id_seq'])
334 # --- scientific_program_id is an integer 343 # --- scientific_program_id is an integer
@@ -351,14 +360,18 @@ class A_Scheduler(Agent): @@ -351,14 +360,18 @@ class A_Scheduler(Agent):
351 sequence_info['visibility_duration'] = visibility_duration # total slots - duration 360 sequence_info['visibility_duration'] = visibility_duration # total slots - duration
352 sequence_info['duration'] = seq_info['sequence']['duration'] 361 sequence_info['duration'] = seq_info['sequence']['duration']
353 sequence_info['scientific_program_id'] = scientific_program_id 362 sequence_info['scientific_program_id'] = scientific_program_id
  363 + sequence_info["period"] = seq_info["sequence"]["period"]
  364 + sequence_info["night_id"] = seq_info["sequence"]["night_id"]
354 self.dprint(f" {scientific_program_id=} range to start={len(kobss)}") 365 self.dprint(f" {scientific_program_id=} range to start={len(kobss)}")
355 if scientific_program_id not in scientific_program_ids: 366 if scientific_program_id not in scientific_program_ids:
356 scientific_program_ids.append(scientific_program_id) 367 scientific_program_ids.append(scientific_program_id)
357 # --- TODO 368 # --- TODO
358 quota_attributes = {} 369 quota_attributes = {}
359 - quota_attributes["total"] = sequence_info["duration"]  
360 - quota_attributes["schedule"] = sequence_info["duration"]  
361 - update_db_quota_sequence(sequence_info["id"], quota_attributes) 370 + quota_attributes["d_total"] = int(np.ceil(sequence_info["duration"]))
  371 + quota_attributes["d_schedule"] = int(np.ceil(sequence_info["duration"]))
  372 + quota_attributes["night_id"] = sequence_info["night_id"]
  373 + quota_attributes["id_period"] = sequence_info["period"]
  374 + self.update_db_quota_sequence(seq_info["sequence"]["id"], quota_attributes)
362 else: 375 else:
363 sequence_info['error'] = f"File {ephfile} not exists" 376 sequence_info['error'] = f"File {ephfile} not exists"
364 sequence_infos.append(sequence_info) 377 sequence_infos.append(sequence_info)
@@ -556,9 +569,12 @@ class A_Scheduler(Agent): @@ -556,9 +569,12 @@ class A_Scheduler(Agent):
556 log.info(f"_compute_schedule_1 finished in {time.time() - t0:.2f} seconds") 569 log.info(f"_compute_schedule_1 finished in {time.time() - t0:.2f} seconds")
557 570
558 def _create_seq_1(self, nb_seq: int): 571 def _create_seq_1(self, nb_seq: int):
  572 + # delete all previous test seq
  573 + Sequence.objects.filter(id__gte=9990000000).delete()
559 t0 = time.time() 574 t0 = time.time()
560 self.dprint("Debut _create_seq_1") 575 self.dprint("Debut _create_seq_1")
561 - seq_template = {'sequence': {'id': 4, 'start_expo_pref': 'IMMEDIATE', 'pyros_user': 2, 'scientific_program': 1, 'name': 'seq_20230628T102140', 'desc': None, 'last_modified_by': 2, 'is_alert': False, 'status': 'TBP', 'with_drift': False, 'priority': None, 'analysis_method': None, 'moon_min': None, 'alt_min': None, 'type': None, 'img_current': None, 'img_total': None, 'not_obs': False, 'obsolete': False, 'processing': False, 'flag': None, 'period': 1, 'start_date': datetime.datetime(2023, 6, 28, 10, 21, 40, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'end_date': datetime.datetime(2023, 6, 28, 10, 21, 40, 999640, tzinfo=datetime.timezone.utc), 'jd1': Decimal('0E-8'), 'jd2': Decimal('0E-8'), 'tolerance_before': '1s', 'tolerance_after': '1min', 'duration': -1.0, 'overhead': Decimal('0E-8'), 'submitted': False, 'config_attributes': {'tolerance_before': '1s', 'tolerance_after': '1min', 'target': 'RADEC 0H10M -15D', 'conformation': 'WIDE', 'layout': 'Altogether'}, 'ra': None, 'dec': None, 'complete': True, 'night_id': '20230627'}, 'albums': {'Altogether': {'plans': [{'id': 4, 'album': 4, 'duration': 0.0, 'nb_fnges': 1, 'config_attributes': {'binnings': {'binxy': [1, 1], 'readouttime': 6}, 'exposuretime': 1.0}, 'complete': True}]}}} 576 + seq_template = yaml.safe_load(open("scheduler_seq_template.yml","r"))
  577 + #{"simplified":True, 'sequence': {'id': 4, 'start_expo_pref': 'IMMEDIATE', 'pyros_user': 2, 'scientific_program': 1, 'name': 'seq_20230628T102140', 'desc': None, 'last_modified_by': 2, 'is_alert': False, 'status': 'TBP', 'with_drift': False, 'priority': None, 'analysis_method': None, 'moon_min': None, 'alt_min': None, 'type': None, 'img_current': None, 'img_total': None, 'not_obs': False, 'obsolete': False, 'processing': False, 'flag': None, 'period': 1, 'start_date': datetime.datetime(2023, 6, 28, 10, 21, 40, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'end_date': datetime.datetime(2023, 6, 28, 10, 21, 40, 999640, tzinfo=datetime.timezone.utc), 'tolerance_before': '1s', 'tolerance_after': '1min', 'duration': -1.0, 'submitted': False, 'config_attributes': {'tolerance_before': '1s', 'tolerance_after': '1min', 'target': 'RADEC 0H10M -15D', 'conformation': 'WIDE', 'layout': 'Altogether'}, 'ra': None, 'dec': None, 'complete': True, 'night_id': '20230627'}, 'albums': {'Altogether': {'plans': [{'id': 4, 'album': 4, 'duration': 0.0, 'nb_fnges': 1, 'config_attributes': {'binnings': {'binxy': [1, 1], 'readouttime': 6}, 'exposuretime': 1.0}, 'complete': True}]}}}
562 # decode general variables info a dict info 578 # decode general variables info a dict info
563 info = self.get_infos() 579 info = self.get_infos()
564 rootdir = info['rootdir'] 580 rootdir = info['rootdir']
@@ -603,35 +619,54 @@ class A_Scheduler(Agent): @@ -603,35 +619,54 @@ class A_Scheduler(Agent):
603 # --- Create new sequences 619 # --- Create new sequences
604 for k in range(nb_seq): 620 for k in range(nb_seq):
605 #print("B"*20 + f" {info['operiod'].id} {info['night']} {k}") 621 #print("B"*20 + f" {info['operiod'].id} {info['night']} {k}")
  622 + if k < nb_seq/2:
  623 + scientific_program = 0
  624 + else:
  625 + scientific_program = 1
  626 +
606 time.sleep(1) 627 time.sleep(1)
607 seq = seq_template.copy() 628 seq = seq_template.copy()
608 - seq['sequence']['period'] = info['operiod'].id # int  
609 - seq['sequence']['night_id'] = info['night'] # str  
610 - seq['sequence']['config_attributes']['target'] = k # int 629 + print(f"{seq}")
  630 + #seq['sequence']['config_attributes']['target'] = k # int
611 # --- 631 # ---
612 - start_expo_pref = "BESTELEV" #"IMMEDIATE"  
613 - scientific_program = int(k/2)  
614 - start_date = datetime.datetime(2023, 6, 28, 10, 21, 40)  
615 - end_date = datetime.datetime(2023, 6, 28, 10, 21, 40, 999640, tzinfo=datetime.timezone.utc) 632 + #start_expo_pref = "BESTELEV" #"IMMEDIATE"
  633 + start_expo_pref = 0 # for bestelev 1, for immediate 0
  634 + start_date,_ = self._fn.night2date(info["night"])
  635 + start_date = start_date + 0.25 + (0.5*k)
  636 + start_date_to_datetime = guitastro.Date(start_date).iso()
  637 + #start_date = datetime.datetime(2023, 6, 28, 10, 21, 40)
  638 + #end_date = datetime.datetime(2023, 6, 28, 10, 21, 40, 999640, tzinfo=datetime.timezone.utc)
616 jd1 = Decimal('0E-8') 639 jd1 = Decimal('0E-8')
617 jd2 = Decimal('0E-8') 640 jd2 = Decimal('0E-8')
618 tolerance_before = '1s' 641 tolerance_before = '1s'
619 - tolerance_after = '1min' 642 + tolerance_after = '5min'
620 duration = 3000.0 643 duration = 3000.0
621 target = f"RADEC {k}h {10+2*k}d" 644 target = f"RADEC {k}h {10+2*k}d"
622 # --- 645 # ---
623 seq['sequence']['start_expo_pref'] = start_expo_pref 646 seq['sequence']['start_expo_pref'] = start_expo_pref
624 seq['sequence']['scientific_program'] = scientific_program 647 seq['sequence']['scientific_program'] = scientific_program
625 - seq['sequence']['start_date'] = start_date  
626 - seq['sequence']['end_date'] = end_date  
627 - seq['sequence']['jd1'] = jd1  
628 - seq['sequence']['jd2'] = jd2 648 + seq['sequence']['start_date'] = start_date_to_datetime
  649 + # seq['sequence']['jd1'] = jd1
  650 + # seq['sequence']['jd2'] = jd2
629 seq['sequence']['tolerance_before'] = tolerance_before 651 seq['sequence']['tolerance_before'] = tolerance_before
630 seq['sequence']['tolerance_after'] = tolerance_after 652 seq['sequence']['tolerance_after'] = tolerance_after
631 - seq['sequence']['duration'] = duration  
632 - seq['sequence']['config_attributes']['target'] = target 653 + seq['sequence']['target'] = target
633 # --- Build the path and file name of the sequence file 654 # --- Build the path and file name of the sequence file
634 - fn_param["id_seq"] = int("999" + f"{k:07d}") 655 + seq["sequence"]["id"] = int("999" + f"{k:07d}")
  656 + seq["sequence"]["name"] = "seq_"+str(seq["sequence"]["id"])
  657 + # Add sequence to db
  658 + # with pyros_api script
  659 + pyros_api = PyrosAPI(None)
  660 + self._fn.fcontext = "pyros_seq_tmp"
  661 + self._fn.extension = ".json"
  662 + seq_fname = self._fn.join(str(seq["sequence"]["id"]))
  663 + seq_file = open(seq_fname,"w")
  664 + seq_file.write(yaml.dump(seq, sort_keys=False))
  665 + seq_file.close()
  666 + response = pyros_api.submit_sequence_file(seq_fname)
  667 + log.info(f"{response}")
  668 +
  669 + """
635 self.dprint(f"{k} : {self._fn.fcontext=}") 670 self.dprint(f"{k} : {self._fn.fcontext=}")
636 self._fn.fname = self._fn.naming_set(fn_param) 671 self._fn.fname = self._fn.naming_set(fn_param)
637 self.dprint(f"{k} : {self._fn.fname=}") 672 self.dprint(f"{k} : {self._fn.fname=}")
@@ -658,6 +693,7 @@ class A_Scheduler(Agent): @@ -658,6 +693,7 @@ class A_Scheduler(Agent):
658 pickle.dump(seq, open(seq_file,"wb")) 693 pickle.dump(seq, open(seq_file,"wb"))
659 #dprint(f"{errors=}") 694 #dprint(f"{errors=}")
660 #dprint("C"*20) 695 #dprint("C"*20)
  696 + """
661 log.info(f"_create_seq_1 finished in {time.time() - t0:.2f} seconds") 697 log.info(f"_create_seq_1 finished in {time.time() - t0:.2f} seconds")
662 698
663 def load_sequence(self): 699 def load_sequence(self):
src/core/pyros_django/scheduling/scheduler_seq_template.yml 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +simplified: True
  2 +sequence:
  3 + scientific_program: 0
  4 + name: seq_20231019T153204
  5 + start_date: '2023-10-19T15:32:04.000000'
  6 + tolerance_before: 1s
  7 + tolerance_after: 1min
  8 + start_expo_pref: 0
  9 + target: RADEC 0H10M -15D
  10 + conformation: 0
  11 + layout: 0
  12 + ALBUMS:
  13 + - Album:
  14 + name: Altogether
  15 + Plans:
  16 + - Plan:
  17 + nb_images: 100
  18 + exposuretime: 10
  19 + binnings: 0