Commit 24be3797cbe226c044521f11437eee97a3df0ba5
1 parent
fafd18bd
Exists in
dev
A_Scheduler real sequence for test with file template
Showing
2 changed files
with
82 additions
and
27 deletions
Show diff stats
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 |