diff --git a/pyscope/observatory/observatory.py b/pyscope/observatory/observatory.py index 6e93310b..2e692e14 100644 --- a/pyscope/observatory/observatory.py +++ b/pyscope/observatory/observatory.py @@ -126,6 +126,9 @@ def __init__(self, config_path=None, **kwargs): self._maxim = None + if not os.path.exists(config_path): + raise ObservatoryException("Config file '%s' not found" % config_path) + if config_path is not None: logger.info( "Using this config file to initialize the observatory: %s" % config_path @@ -2258,18 +2261,18 @@ def take_flats( self.telescope.Tracking = False logger.info("Tracking off") - if self.cover_calibrator is not None: + '''if self.cover_calibrator is not None: if self.cover_calibrator.CoverState != "NotPresent": logger.info("Opening the cover calibrator") self.cover_calibrator.OpenCover() - logger.info("Cover open") + logger.info("Cover open")''' if gain is not None: logger.info("Setting the camera gain to %i" % gain) self.camera.Gain = gain logger.info("Camera gain set") - for filt, filt_exp in zip(filters, filter_exposures): + for filt, filt_exp, idx in zip(filters, filter_exposures, range(len(filters))): # skip filters with 0 exposure time if filt_exp == 0: @@ -2287,9 +2290,9 @@ def take_flats( if type(filter_brightness) is list: logger.info( "Setting the cover calibrator brightness to %i" - % filter_brightness[i] + % filter_brightness[idx] ) - self.cover_calibrator.CalibratorOn(filter_brightness[i]) + self.cover_calibrator.CalibratorOn(filter_brightness[idx]) logger.info("Cover calibrator on") else: logger.warning("Cover calibrator not available, assuming sky flats") @@ -2351,7 +2354,7 @@ def take_flats( iter_save_name = Path( ( str(iter_save_name) - + (f"_Bright{filter_brightness[i]}" + "_{j}.fts") + + (f"_Bright{filter_brightness[idx]}" + f"_{j}.fts") ) ) else: @@ -2878,32 +2881,32 @@ def cover_calibrator_info(self): "CALSTATE": (self.cover_calibrator.CalibratorState, "Calibrator state"), "COVSTATE": (self.cover_calibrator.CoverState, "Cover state"), "BRIGHT": (None, "Brightness of cover calibrator"), - "CCNAME": (self.cover_calibrator.Name, "Cover calibrator name"), - "COVCAL": (self.cover_calibrator.Name, "Cover calibrator name"), - "CCDRVER": ( - self.cover_calibrator.DriverVersion, - "Cover calibrator driver version", - ), - "CCDRV": ( - str(self.cover_calibrator.DriverInfo), - "Cover calibrator driver info", - ), - "CCINTF": ( - self.cover_calibrator.InterfaceVersion, - "Cover calibrator interface version", - ), - "CCDESC": ( - self.cover_calibrator.Description, - "Cover calibrator description", - ), - "MAXBRITE": ( - self.cover_calibrator.MaxBrightness, - "Cover calibrator maximum possible brightness", - ), - "CCSUPAC": ( - str(self.cover_calibrator.SupportedActions), - "Cover calibrator supported actions", - ), + # "CCNAME": (self.cover_calibrator.Name, "Cover calibrator name"), + # "COVCAL": (self.cover_calibrator.Name, "Cover calibrator name"), + # "CCDRVER": ( + # self.cover_calibrator.DriverVersion, + # "Cover calibrator driver version", + # ), + # "CCDRV": ( + # str(self.cover_calibrator.DriverInfo), + # "Cover calibrator driver info", + # ), + # "CCINTF": ( + # self.cover_calibrator.InterfaceVersion, + # "Cover calibrator interface version", + # ), + # "CCDESC": ( + # self.cover_calibrator.Description, + # "Cover calibrator description", + # ), + # "MAXBRITE": ( + # self.cover_calibrator.MaxBrightness, + # "Cover calibrator maximum possible brightness", + # ), + # "CCSUPAC": ( + # str(self.cover_calibrator.SupportedActions), + # "Cover calibrator supported actions", + # ), } try: info["BRIGHT"] = (self.cover_calibrator.Brightness, info["BRIGHT"][1]) diff --git a/pyscope/telrun/schedtel.py b/pyscope/telrun/schedtel.py index fb2676a5..65894208 100644 --- a/pyscope/telrun/schedtel.py +++ b/pyscope/telrun/schedtel.py @@ -1118,37 +1118,59 @@ def plot_schedule_sky_cli(schedule_table, observatory): "Observatory must be, a string, Observatory object, or astroplan.Observer object." ) return - - # Get list of targets (and their ra/dec) and start times and insert into - # a dictionary with the target as the key and a list of start times as the value - targets = {} - for block in schedule_table: - if block["name"] == "TransitionBlock" or block["name"] == "EmptyBlock": + + # Get unique targets in the schedule + target_times = {} + + for row in schedule_table: + if row["name"] == "TransitionBlock" or row["name"] == "EmptyBlock": continue + target_string = row["target"].to_string("hmsdms") + target_name = row["name"] + if target_string not in target_times: + target_times[target_string] = { + "name": target_name, + "times": [row["start_time"]], + } + else: + target_times[target_string]["times"].append(row["start_time"]) - if block["name"] not in targets: - targets[block["name"]] = [] - obs_time = astrotime.Time(np.float64(block["start_time"].jd), format="jd") - targets[block["name"]].append(obs_time) + # targets = [t.to_string("hmsdms") for t in schedule_table["target"]] fig, ax = plt.subplots(1, 1, figsize=(7, 7), subplot_kw={"projection": "polar"}) - # Plot new axes for each target only, not each start time - for target in targets: + for target, target_dict in target_times.items(): + times = target_dict["times"] + try: + label = target_dict["name"].strip() + except: + label = target + target = coord.SkyCoord(target, unit=(u.hourangle, u.deg)) ax = astroplan_plots.plot_sky( - astroplan.FixedTarget(coord.SkyCoord.from_name(target)), + astroplan.FixedTarget(target), observatory, - targets[target], + times, ax=ax, - style_kwargs={ - "label": target, - }, + style_kwargs={"label": label}, ) handles, labels = ax.get_legend_handles_labels() - unique = [ - (h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i] - ] - ax.legend(*zip(*unique), loc=(1.1, 0)) + # unique = [ + # (h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i] + # ] + # ax.legend(*zip(*unique), loc=(1.1, 0)) + + + + # Add title to plot based on date + t0 = np.min(schedule_table["start_time"]) # -1 corrects for UTC to local time, should be cleaned up + t0 = astrotime.Time(t0, format="mjd") + t0.format = "iso" + + ax.set_title(f"Observing Schedule: Night of {t0.to_string().split(' ')[0]} UTC", + fontsize=14 + ) + + ax.legend(labels, loc=(1.1, 0)) fig.set_facecolor("white") fig.set_dpi(300) diff --git a/pyscope/telrun/telrun_operator.py b/pyscope/telrun/telrun_operator.py index cc5bca22..277c472f 100644 --- a/pyscope/telrun/telrun_operator.py +++ b/pyscope/telrun/telrun_operator.py @@ -1446,6 +1446,23 @@ def execute_block(self, *args, slew=True, **kwargs): logger.info("Setting camera readout mode to %s" % self.default_readout) self.observatory.camera.ReadoutMode = self.default_readout + # TODO: Make this better - temporary fix 2024-11-15 + # Check if focuser is outside of self.autofocus_midpoint +/- 1000 + if ( + self.observatory.focuser.Position + < self.autofocus_midpoint - 1000 + or self.observatory.focuser.Position + > self.autofocus_midpoint + 1000 + ): + logger.info( + "Focuser position is outside of autofocus_midpoint +/- 1000, moving to autofocus_midpoint..." + ) + self._focuser_status = "Moving" + self.observatory.focuser.Move(self.autofocus_midpoint) + while self.observatory.focuser.IsMoving: + time.sleep(0.1) + self._focuser_status = "Idle" + logger.info("Starting autofocus, ensuring tracking is on...") self.observatory.telescope.Tracking = True t = threading.Thread(