Commit 9b6af71d7acd0209c07f1e842d17fcbfc4561ea6
1 parent
8e3c40f8
Exists in
dev
Update version Scheduler
Showing
2 changed files
with
98 additions
and
18 deletions
Show diff stats
src/core/pyros_django/majordome/agent/Agent.py
... | ... | @@ -3482,13 +3482,13 @@ class Agent: |
3482 | 3482 | if loginfo: |
3483 | 3483 | log.info(self._oc['config'].fn.fcontexts_human()) |
3484 | 3484 | |
3485 | - def ephem_target2night(self, target:str) -> dict: | |
3485 | + def ephem_target2night(self, target:str, date: str="now") -> dict: | |
3486 | 3486 | eph = Ephemeris() |
3487 | 3487 | eph.set_home(self._oc['config'].getHome()) |
3488 | 3488 | fcontext0 = self._oc['config'].fn.fcontext |
3489 | 3489 | # --- Build the path and file name of the sun ephemeris |
3490 | 3490 | self._oc['config'].fn.fcontext = "pyros_eph" |
3491 | - night = self._oc['config'].fn.date2night("now") | |
3491 | + night = self._oc['config'].fn.date2night(date) | |
3492 | 3492 | operiod = Period.objects.exploitation_period() |
3493 | 3493 | if operiod == None: |
3494 | 3494 | log.info("No period valid in the database") |
... | ... | @@ -3506,8 +3506,8 @@ class Agent: |
3506 | 3506 | "unit": self._oc['config'].unit_name, |
3507 | 3507 | "target": target |
3508 | 3508 | } |
3509 | - fname = self._fn.naming_set(fn_param) | |
3510 | - eph_file = self._fn.joinabs(fname) | |
3509 | + fname = self._oc['config'].fn.naming_set(fn_param) | |
3510 | + eph_file = self._oc['config'].fn.joinabs(fname) | |
3511 | 3511 | # --- Compute the sun ephemeris if needed. Save it as pickle. |
3512 | 3512 | if not os.path.exists(eph_file): |
3513 | 3513 | ephem_target = eph.target2night(target, night, None, None) | ... | ... |
src/core/pyros_django/scheduling/A_Scheduler.py
... | ... | @@ -127,6 +127,9 @@ class A_Scheduler(Agent): |
127 | 127 | self.check_contexts(True) |
128 | 128 | log.info(f"{self._fn.longitude=}") |
129 | 129 | |
130 | + # TBD duskelev a parametrer from obsconfig (yml) | |
131 | + self._duskelev = -7 | |
132 | + | |
130 | 133 | # === Status of routine processing |
131 | 134 | self._routine_running = self.RUNNING_NOTHING |
132 | 135 | log.debug("end init()") |
... | ... | @@ -229,6 +232,14 @@ class A_Scheduler(Agent): |
229 | 232 | subdir = info['subdir'] |
230 | 233 | # --- Get the night |
231 | 234 | night = info['night'] |
235 | + # --- Get ephemeris informations of the night and initialize quotas | |
236 | + night_info = self.update_sun_moon_ephems() | |
237 | + quota_total_period = night_info['total'][1] | |
238 | + quota_total_night_start = night_info[night][0] | |
239 | + quota_total_night_end = night_info[night][1] | |
240 | + self.dprint(f"{quota_total_period=}") | |
241 | + self.dprint(f"{quota_total_night_start=}") | |
242 | + self.dprint(f"{quota_total_night_end=}") | |
232 | 243 | # --- Build the wildcard to list the sequences |
233 | 244 | wildcard = os.path.join(rootdir, subdir, "*.p") |
234 | 245 | self.dprint(f"{wildcard=}") |
... | ... | @@ -529,18 +540,16 @@ class A_Scheduler(Agent): |
529 | 540 | rootdir = info['rootdir'] |
530 | 541 | subdir = info['subdir'] |
531 | 542 | |
532 | - # --- Prepare ephemeris object | |
533 | - # TBD duskelev a parametrer from obsconfig (yml) | |
534 | - duskelev = -7 | |
535 | - eph = guitastro.Ephemeris() | |
536 | - eph.set_home(self.config.getHome()) | |
537 | - | |
538 | - # --- Build the path and file name of the sun ephemeris | |
543 | + # --- Read or create the sun ephemeris | |
539 | 544 | ephem_sun = self.ephem_target2night("sun") |
540 | 545 | |
541 | - # --- Build the path and file name of the moon ephemeris | |
546 | + # --- Read or create the moon ephemeris | |
542 | 547 | ephem_moon = self.ephem_target2night("moon") |
543 | 548 | |
549 | + # --- Prepare ephemeris object | |
550 | + eph = guitastro.Ephemeris() | |
551 | + eph.set_home(self.config.getHome()) | |
552 | + | |
544 | 553 | # --- Horizon (TBD get from config) |
545 | 554 | self.dprint("Debut _create_seq_1 Horizon") |
546 | 555 | hor = guitastro.Horizon(eph.home) |
... | ... | @@ -613,7 +622,7 @@ class A_Scheduler(Agent): |
613 | 622 | #print(f"{k} : TRY") |
614 | 623 | errors = [] |
615 | 624 | try: |
616 | - ephem = eph.target2night(seq["sequence"]["config_attributes"]["target"], info['night'], ephem_sun, ephem_moon, preference=seq['sequence']['start_expo_pref'], duskelev=duskelev, horizon=hor, duration=duration) | |
625 | + ephem = eph.target2night(seq["sequence"]["config_attributes"]["target"], info['night'], ephem_sun, ephem_moon, preference=seq['sequence']['start_expo_pref'], duskelev=self._duskelev, horizon=hor, duration=duration) | |
617 | 626 | except ValueError: |
618 | 627 | errors.append("Target value is not valid") |
619 | 628 | except guitastro.ephemeris.EphemerisException as ephemException: |
... | ... | @@ -630,7 +639,80 @@ class A_Scheduler(Agent): |
630 | 639 | def load_sequence(self): |
631 | 640 | sequence = "" |
632 | 641 | return sequence |
642 | + | |
643 | + def update_sun_moon_ephems(self): | |
644 | + """Update the files in the ephems folder. | |
633 | 645 | |
646 | + The file 'duration.pickle' contains the start, end for each night and other informations to make quota computations. | |
647 | + | |
648 | + Check if the file 'duration.pickle' exists in the ephem/period directory. | |
649 | + If yes, returns the contents of the 'duration.pickle' file. | |
650 | + If not, check each ephemeris file existance for Sun and Moon and compute them if needed. | |
651 | + | |
652 | + Returns: | |
653 | + Dictionary with night string as key. Values are a list of integers: | |
654 | + | |
655 | + * total1: Cumulative sum of seconds of previous night durations at the start of the night. | |
656 | + * total2: Cumulative sum of seconds of previous night durations at the end of the night. | |
657 | + * total_night: Number of seconds available during this night. | |
658 | + * sec1: Index of seconds for the start of the night. | |
659 | + * sec2: Index of seconds for the end of the night. | |
660 | + | |
661 | + """ | |
662 | + | |
663 | + # --- Get the period object | |
664 | + operiod = Period.objects.exploitation_period() | |
665 | + | |
666 | + # --- Get the period ID | |
667 | + period_id = operiod.get_period_id_as_str() | |
668 | + | |
669 | + # --- Select the context of ephemeris | |
670 | + fcontext0 = self._oc['config'].fn.fcontext | |
671 | + self._oc['config'].fn.fcontext = "pyros_eph" | |
672 | + | |
673 | + # --- Check if durations.pickle file exists | |
674 | + rootdir = self._oc['config'].fn.rootdir | |
675 | + filename = os.path.join(rootdir, period_id, "durations.pickle") | |
676 | + self.dprint(f"Read {filename=}") | |
677 | + if os.path.exists(filename): | |
678 | + self._oc['config'].fn.fcontext = fcontext0 | |
679 | + return pickle.load(open(filename, "wb")) | |
680 | + | |
681 | + # --- Get the period limit dates jd1, jd2 | |
682 | + self.dprint(f"{dir(operiod)=}") | |
683 | + d = operiod.start_date.isoformat() | |
684 | + night_start = d[0:4]+d[5:7]+d[8:10] | |
685 | + jd1, _ = self.config.fn.night2date(night_start) | |
686 | + d = operiod.end_date.isoformat() | |
687 | + night_end = d[0:4]+d[5:7]+d[8:10] | |
688 | + jd2, _ = self.config.fn.night2date(night_end) | |
689 | + self.dprint(f"{night_start=} {night_end=}") | |
690 | + self.dprint(f"{jd1=} {jd2=}") | |
691 | + | |
692 | + # --- Loop over dates of the period to create ephems | |
693 | + targets = ['sun', 'moon'] | |
694 | + jd = jd1 + 0.1 | |
695 | + total1 = 0 | |
696 | + night_info = {} | |
697 | + while jd < jd2: | |
698 | + night = self._oc['config'].fn.date2night(jd) | |
699 | + for target in targets: | |
700 | + self.dprint(f"{night=} {target=}") | |
701 | + ephem = self.ephem_target2night(target, jd) | |
702 | + if target == "sun": | |
703 | + ks = np.where(ephem['alt'] < self._duskelev) | |
704 | + total_night = len(ks[0]) | |
705 | + total2 = total1 + total_night | |
706 | + sec1 = ks[0][0] | |
707 | + sec2 = ks[0][-1] | |
708 | + night_info[night] = [int(total1), int(total2), int(total_night), sec1, sec2] | |
709 | + total1 = total2 | |
710 | + jd += 1 | |
711 | + night_info['total'] = [0, int(total2), int(total2), -1, -1] | |
712 | + self.dprint(f"Write {filename=}") | |
713 | + pickle.dump(night_info, open(filename, "wb")) | |
714 | + return night_info | |
715 | + | |
634 | 716 | def get_infos(self): |
635 | 717 | self._fn.fcontext = "pyros_seq" |
636 | 718 | rootdir = self._fn.rootdir |
... | ... | @@ -639,11 +721,9 @@ class A_Scheduler(Agent): |
639 | 721 | log.info("No period valid in the database") |
640 | 722 | self._routine_running = self.RUNNING_NOTHING |
641 | 723 | return |
642 | - period_id = str(operiod.id) | |
643 | - if len(str(operiod.id)) < 3: | |
644 | - while len(period_id) < 3: | |
645 | - period_id = "0" + period_id | |
646 | - period_id = "P" + period_id | |
724 | + # retourne un str -> id de la période sous le format Pxxx | |
725 | + period_id = operiod.get_period_id_as_str() | |
726 | + | |
647 | 727 | night_id = self._fn.date2night("now") |
648 | 728 | subdir = os.path.join(period_id, night_id) |
649 | 729 | dico = {} | ... | ... |