def flicamera(ctx, cameras, config_path, simulate, simulation_profile, verbose): """Command Line Interface for Finger Lakes Instrumentation cameras.""" if verbose: log.set_level(logging.DEBUG) else: log.set_level(logging.WARNING) # We want to allow the actor to minimally work without a configuration # file so instead of passing it to the actor using the .from_config # classmethod we parse the configuration ourselves. config = None if not config_path: config_path = f"{os.path.dirname(__file__)}/etc/flicamera.yaml" config = read_yaml_file(config_path) if config: if "cameras" in config: camera_config = config["cameras"].copy() else: camera_config = config.copy() # type: ignore log_file = config.get("log_file", None) if log_file: log_file = log_file.format(hostname=socket.getfqdn()) else: log_file = None camera_config = None include = cameras or None simulate_config: Union[bool, Dict[str, Any]] if simulate is True: if not config: raise RuntimeError("Cannot simulate without a configuration file.") elif "simulation" not in config: raise RuntimeError("'simulate' section not found in config file.") if "profiles" in config["simulation"]: simulate_config = config["simulation"]["profiles"][simulation_profile] else: simulate_config = config["simulation"] else: simulate_config = False ctx.obj["camera_system"] = FLICameraWrapper( camera_config=camera_config, include=include, log_file=log_file, verbose=verbose, config_path=config_path, simulate_config=simulate_config, ) # Store some of the options here for the daemon ctx.obj["cameras"] = cameras ctx.obj["config"] = config ctx.obj["verbose"] = verbose
async def actor(): config = read_yaml_file(config_path) hal_actor = HALActor.from_config(config) hal_actor = await setup_test_actor(hal_actor) # type: ignore yield hal_actor # Clear replies in preparation for next test. hal_actor.mock_replies.clear()
def _parse_config( input: Union[Dict[str, Any], pathlib.Path, str], loader=yaml.FullLoader, ) -> Dict[str, Any]: if not isinstance(input, dict): input = pathlib.Path(input) assert input.exists(), "configuration path does not exist." config = read_yaml_file(str(input), loader=loader) else: config = input return cast("Dict[str, Any]", config)
def flicamera(ctx, cameras, config_path, verbose): """Command Line Interface for Finger Lakes Instrumentation cameras.""" if verbose: log.set_level(logging.NOTSET) else: log.set_level(logging.WARNING) # We want to allow the actor to minimally work without a configuration # file so instead of passing it to the actor using the .from_config # classmethod we parse the configuration ourselves. config = None if not config_path: config_path = f'{os.path.dirname(__file__)}/etc/flicamera.yaml' config = read_yaml_file(config_path) if config: if 'cameras' in config: camera_config = config['cameras'].copy() else: camera_config = config.copy() log_file = config.get('log_file', None) if log_file: log_file = log_file.format(hostname=socket.getfqdn()) else: log_file = None camera_config = None include = cameras or None ctx.obj['camera_system'] = FLICameraWrapper(camera_config=camera_config, include=include, log_file=log_file, verbose=verbose, config_path=config_path) # Store some of the options here for the daemon ctx.obj['cameras'] = cameras ctx.obj['config'] = config ctx.obj['verbose'] = verbose
async def flicamera(camera_name): """Starts an actor and sets CAMERA-NAME as the default camera. It is expected that the information for the actor is found in $SDSSCORE_DIR/configuration_files/actors/flicamera.yaml under the actor section. Any additional flags passed are used to override the default configuration values. """ config_file = os.path.join(os.environ['SDSSCORE_DIR'], 'configuration_files/actors/flicamera.yaml') if not os.path.exists(config_file): raise RuntimeError(f'cannot open file {config_file}.') actor_config = read_yaml_file(config_file).get('actor') if not actor_config: raise RuntimeError('cannot find actor section in configuration file.') if 'log_dir' in actor_config: actor_config['log_dir'] = os.path.join(actor_config['log_dir'], camera_name) else: actor_config['log_dir'] = f'/data/logs/actors/{camera_name}' camera_system = FLICameraSystem().setup() await camera_system.start_camera_poller() await asyncio.sleep(0.1) # Some time to allow camera to connect. actor = await FLIActor.from_config(actor_config, camera_system, name=camera_name, default_cameras=[camera_name]).start() actor.timer_commands.append(TimerCommand('status', delay=60)) await actor.run_forever()
def __init__(self, fields, output_dir, observatory=None, config_file=None, n_attempts=10): self.output_dir = pathlib.Path(output_dir) if config_file: config_data = read_yaml_file(config_file) else: config_data = config self.config_data = config_data.copy() self.observatory = observatory or self.config_data['observatory'] self.n_attempts = n_attempts numpy.random.seed(config_data['seed']) if isinstance(fields, int): fields = get_uniform_ra_dec(fields).tolist() self.fields = { fid + 1: list(map(float, fields[fid])) for fid in range(len(fields)) } elif isinstance(fields, dict): self.fields = fields elif isinstance(fields, (tuple, list)): self.fields = { fid + 1: list(map(float, fields[fid])) for fid in range(len(fields)) } self._data = None
def config(): """Gets the test configuration.""" yield read_yaml_file(TEST_DATA)
def config(): return read_yaml_file(TEST_CONFIG_FILE)
def __init__(self, targeting_plan, config_file=None, schema=None, table_name=None): assert self.name, 'carton subclass must override name' assert self.category, 'carton subclass must override category' assert self.program, 'carton subclass must override program' self.plan = targeting_plan self.tag = __version__ if self.plan != '0.0.0-test' else None if config_file: this_config = read_yaml_file(config_file) else: this_config = config.copy() if self.plan not in this_config: raise TargetSelectionError( f'({self.name}): cannot find plan {self.plan!r} in config.') self.config = this_config[self.plan] if 'parameters' in self.config: self.parameters = self.config['parameters'].get(self.name, None) else: self.parameters = None try: self.xmatch_plan = self.config['xmatch_plan'] except KeyError: raise TargetSelectionError( f'({self.name}): xmatch_plan not found in config.') # Check the signature of build_query self._build_query_signature = inspect.signature(self.build_query) if 'version_id' not in self._build_query_signature.parameters: raise TargetSelectionError( 'build_query does not accept version_id') self.database = tdb.database assert self.database.connected, 'database is not connected.' self.schema = schema or self.config.get('schema', None) or 'sandbox' self.table_name = table_name or f'temp_{self.name}'.replace('-', '_') self.RModel = None if self.cadence: ncad = tdb.Cadence.select().where( tdb.Cadence.label == self.cadence).count() assert ncad == 1, f'{self.cadence!r} does not exist in targetdb.cadence.' self.log = log self.has_run = False self._disable_query_log = False # We cannot set temp_buffers multiple times if there are temporary tables # (as in add_optical_magnitudes) so we set it here. if ('database_options' in self.config and 'temp_buffers' in self.config['database_options']): temp_buffers = self.config['database_options'].pop('temp_buffers') self.database.execute_sql(f'SET temp_buffers = \'{temp_buffers}\'')
def test_config(): """Yield the test configuration as a dictionary.""" yield read_yaml_file(TEST_CONFIG_FILE)
def __init__( self, fps: FPS, trajectories: str | pathlib.Path | TrajectoryDataType, dump: bool | str = True, extra_dump_data: dict[str, Any] = {}, ): self.fps = fps self.trajectories: TrajectoryDataType if self.fps.locked: raise FPSLockedError( f"FPS is locked by {fps.locked_by}. Cannot send trajectories.") if self.fps.moving: raise TrajectoryError( "The FPS is moving. Cannot send new trajectory.", self, ) if isinstance(trajectories, (str, pathlib.Path)): path = pathlib.Path(trajectories) if path.suffix == ".json": self.trajectories = json.loads(open(path, "r").read())["trajectory"] else: self.trajectories = cast(dict, read_yaml_file(trajectories)) elif isinstance(trajectories, dict): self.trajectories = trajectories else: raise TrajectoryError("invalid trajectory data.", self) # List of positioners that failed receiving the trajectory and reason. self.failed_positioners: dict[int, str] = {} self.validate() #: Number of points sent to each positioner as a tuple ``(alpha, beta)``. self.n_points = {} #: The time required to complete the trajectory. self.move_time: float | None = None #: How long it took to send the trajectory. self.data_send_time: float | None = None self.failed = False self.send_new_trajectory_failed = False # Commands that will be sent. Mostly for inspection if the trajectory fails. self.data_send_cmd: Command | None = None self.end_traj_cmds: Command | None = None self.start_time: float | None = None self.end_time: float | None = None self.use_sync_line: bool = True self._ready_to_start = False self.dump_data = { "start_time": time.time(), "success": False, "trajectory_send_time": None, "trajectory_start_time": None, "end_time": None, "use_sync_line": True, "extra": extra_dump_data, "trajectory": self.trajectories, "initial_positions": self.fps.get_positions_dict(), "final_positions": {}, } if dump is False: self.dump_file = None elif isinstance(dump, (str, pathlib.Path)): self.dump_file = str(dump) else: dirname = config["positioner"]["trajectory_dump_path"] mjd = str(int(Time.now().mjd)) dirname = os.path.join(dirname, mjd) files = list(sorted(glob(os.path.join(dirname, "*.json")))) if len(files) == 0: seq = 1 else: seq = int(files[-1].split("-")[-1].split(".")[0]) + 1 self.dump_file = os.path.join(dirname, f"trajectory-{mjd}-{seq:04d}.json")
def __init__( self, camera_class: Optional[Type[_T_BaseCamera]] = None, camera_config: Optional[Union[AnyPath, Dict[str, Any]]] = None, include: Optional[List[Any]] = None, exclude: Optional[List[Any]] = None, logger: Optional[SDSSLogger] = None, log_header: Optional[str] = None, log_file: Optional[AnyPath] = None, verbose: Optional[Union[bool, int]] = False, ): self.camera_class = camera_class or self.camera_class if not self.camera_class or not issubclass(self.camera_class, BaseCamera): raise ValueError("camera_class must be a subclass of BaseCamera.") self.include = self.include or include self.exclude = self.exclude or exclude logger_name = self.__class__.__name__.upper() self.log_header = log_header or f"[{logger_name.upper()}]: " self.logger = logger or cast(SDSSLogger, get_logger(logger_name)) if verbose: self.logger.sh.setLevel(int(verbose)) else: self.logger.sh.setLevel(logging.WARNING) if log_file: self.logger.start_file_logger(str(log_file)) if self.logger.fh: assert self.logger.fh.formatter self.logger.fh.formatter.converter = time.gmtime self.log(f"logging to {log_file}") self.loop = asyncio.get_event_loop() self.loop.set_exception_handler(self.logger.asyncio_exception_handler) #: list: The list of cameras being handled. self.cameras: List[_T_BaseCamera] = [] self._camera_poller = None #: .EventNotifier: Notifies of `.CameraSystemEvent` and `.CameraEvent` events. self.notifier = EventNotifier() self._config: Optional[Dict[str, Any]] = None if camera_config: if isinstance(camera_config, dict): self._config = camera_config.copy() else: self._config = cast(Dict[str, Any], read_yaml_file(str(camera_config))) self.log(f"read configuration file from {camera_config}") # If the config has a section named "cameras", prefer that. if self._config is not None: if isinstance(self._config.get("cameras", None), dict): self._config = self._config["cameras"] assert self._config is not None uids = [self._config[camera]["uid"] for camera in self._config] if len(uids) != len(set(uids)): raise ValueError("repeated UIDs in the configuration data.") self.running: bool = False