예제 #1
0
    def __init__(self,
                 port: int = 37075,
                 cache_size: int = 25,
                 *args,
                 **kwargs):
        """Initializes file cache.

        Args:
            port: Port for HTTP server.
            cache_size: Size of file cache, i.e. number of files to cache.
        """
        Module.__init__(self, *args, **kwargs)

        # add thread func
        self._add_thread_func(self._http, False)

        # init tornado web server
        tornado.web.Application.__init__(self, [
            (r"/(.*)", MainHandler),
        ])

        # store stuff
        self._io_loop = None
        self._cache = DataCache(cache_size)
        self._lock = threading.RLock()
        self._is_listening = False
        self._port = port
        self._cache_size = cache_size
예제 #2
0
    def __init__(self, *args, **kwargs):
        """Initialize a new base roof."""
        Module.__init__(self, *args, **kwargs)

        # init mixins
        WeatherAwareMixin.__init__(self, *args, **kwargs)
        MotionStatusMixin.__init__(self, *args, **kwargs)
예제 #3
0
    def __init__(self, telescope: Union[str, ITelescope], camera: Union[str, ICamera],
                 filters: Union[str, IFilters], flat_fielder: Union[dict, FlatFielder],
                 log_file: str = None, *args, **kwargs):
        """Initialize a new flat fielder.

        Args:
            telescope: Name of ITelescope.
            camera: Name of ICamera.
            filters: Name of IFilters, if any.
            pointing: Pointing to use.
            log_file: Name of file to store flat field log in.
        """
        Module.__init__(self, *args, **kwargs)

        # store telescope, camera, and filters
        self._telescope = telescope
        self._camera = camera
        self._filters = filters
        self._abort = threading.Event()

        # flat fielder
        self._flat_fielder = get_object(flat_fielder, FlatFielder, vfs=self.vfs,
                                        observer=self.observer, callback=self.callback)

        # init log file
        self._publisher = None if log_file is None else CsvPublisher(log_file)
예제 #4
0
    def __init__(self, telescope: Union[str, ITelescope], camera: Union[str, ICamera],
                 target_pixel: Tuple = None, attempts: int = 5, tolerance: float = 1,
                 max_offset: float = 120, log_file: str = None, *args, **kwargs):
        """Create a new base acquisition.

        Args:
            telescope: Name of ITelescope.
            camera: Name of ICamera.
            target_pixel: (x, y) tuple of pixel that the star should be positioned on. If None, center of image is used.
            attempts: Number of attempts before giving up.
            tolerance: Tolerance in position to reach in arcsec.
            max_offset: Maximum offset to move in arcsec.
            log_file: Name of file to write log to.
        """
        Module.__init__(self, *args, **kwargs)

        # store telescope and camera
        self._telescope = telescope
        self._camera = camera

        # store
        self._target_pixel = target_pixel
        self._attempts = attempts
        self._tolerance = tolerance
        self._max_offset = max_offset

        # init log file
        self._publisher = CsvPublisher(log_file)

        # init camera settings mixin
        CameraSettingsMixin.__init__(self, *args, **kwargs)
예제 #5
0
    def __init__(self,
                 pipeline: Union[dict, Pipeline],
                 archive: Union[dict, Archive],
                 sources: Union[str, List[str]] = None,
                 cache_size: int = 20,
                 *args,
                 **kwargs):
        """Creates a new image writer.

        Args:
            pipeline: Pipeline to use for reduction.
            archive: Used for retrieving calibration files. If None, no calibration is done.
            sources: List of sources (e.g. cameras) to process images from or None for all.
            cache_size: Size of cache for calibration files.
        """
        Module.__init__(self, *args, **kwargs)

        # stuff
        self._sources = [sources] if isinstance(sources, str) else sources
        self._queue = Queue()
        self._archive = None if archive is None else get_object(
            archive, Archive)
        self._pipeline = get_object(pipeline, Pipeline)
        self._cache = DataCache(size=cache_size)

        # add thread func
        self._add_thread_func(self._worker, True)
예제 #6
0
    def __init__(self,
                 watchpath: str = None,
                 destinations: list = None,
                 *args,
                 **kwargs):
        """Create a new image watcher.

        Args:
            watchpath: Path to watch.
            destinations: Filename patterns for destinations.
        """
        Module.__init__(self, *args, **kwargs)

        # test import
        import pyinotify

        # add thread func
        self._add_thread_func(self._worker, True)

        # variables
        self._watchpath = watchpath
        self._notifier = None
        self._queue = Queue()

        # filename patterns
        if not destinations:
            raise ValueError(
                'No filename patterns given for the destinations.')
        self._destinations = destinations
예제 #7
0
    def __init__(self,
                 min_alt: int = 30,
                 max_alt: int = 85,
                 num_alt: int = 8,
                 num_az: int = 24,
                 finish: int = 90,
                 exp_time: float = 1.,
                 acquisition: str = 'acquisition',
                 *args,
                 **kwargs):
        """Initialize a new auto focus system.

        Args:
            min_alt: Mininum altitude to use.
            max_alt: Maximum altidude to use.
            num_alt: Number of altitude points to create on grid.
            num_az: Number of azimuth points to create on grid.
            finish: When this number in percent of points have been finished, terminate mastermind.
            exp_time: Exposure time in secs.
            acquisition: IAcquisition unit to use.
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._min_alt = min_alt
        self._max_alt = max_alt
        self._num_alt = num_alt
        self._num_az = num_az
        self._finish = 1. - finish / 100.
        self._exp_time = exp_time
        self._acquisition = acquisition

        # add thread func
        self._add_thread_func(self._run_thread, False)
예제 #8
0
    def __init__(self,
                 url: str = None,
                 system_init_time: int = 300,
                 *args,
                 **kwargs):
        """Initialize a new pyobs-weather connector.

        Args:
            url: URL to weather station
            system_init_time: Time in seconds the full system needs to initialize
        """
        Module.__init__(self, *args, **kwargs)

        # store and create session
        self._system_init_time = system_init_time
        self._url = url
        self._session = requests.session()

        # current status
        self._is_good = None

        # whole status
        self._status: Dict[str, Any] = {}
        self._status_lock = threading.RLock()

        # add thread func
        self._add_thread_func(self._update, True)
예제 #9
0
    def __init__(self,
                 focuser: Union[str, IFocuser],
                 camera: Union[str, ICamera],
                 filters: Union[str, IFilters] = None,
                 offset: bool = False,
                 *args,
                 **kwargs):
        """Initialize a new auto focus system.

        Args:
            focuser: Name of IFocuser.
            camera: Name of ICamera.
            filters: Name of IFilters, if any.
            offset: If True, offsets are used instead of absolute focus values.
        """
        Module.__init__(self, *args, **kwargs)

        # test import
        import lmfit

        # store focuser and camera
        self._focuser = focuser
        self._camera = camera
        self._filters = filters
        self._offset = offset
        self._abort = threading.Event()

        # storage for data
        self._data_lock = threading.RLock()
        self._data: List[Dict[str, float]] = []
예제 #10
0
    def __init__(self, warn_sound: str, warn_interval: float = 1,
                 start_sound: str = None, started_sound: str = None, stop_sound: str = None, stopped_sound: str = None,
                 player: str = 'mpg123', trigger_file: str = None, *args, **kwargs):
        """Initialize a new warning.

        Args:
            warn_sound: Name of file to play.
            warn_interval: Interval in seconds between sounds.
            start_sound: Sound to play when starting systems.
            started_sound: Sound to play when systems started.
            stop_sound: Sound to play when stopping systems.
            stopped_sound: Sound to play when systems stopped.
            trigger_file: File, which triggers to switch on-off and vice versa, when created.
                Will be deleted afterwards.
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._warn_sound = warn_sound
        self._warn_interval = warn_interval
        self._start_sound = start_sound
        self._started_sound = started_sound
        self._stop_sound = stop_sound
        self._stopped_sound = stopped_sound
        self._trigger_file = trigger_file
        self._player = player
        self._autonomous = False

        # threads
        self._add_thread_func(self._heartbeat)
        self._add_thread_func(self._check_autonomous)
        self._add_thread_func(self._check_trigger)
예제 #11
0
    def __init__(self, telescope: typing.Union[str, ITelescope],
                 pointing: typing.Union[dict, SkyFlatsBasePointing], *args,
                 **kwargs):
        """Initialize a new flat field pointing.

        Args:
            telescope: Telescope to point
            pointing: Pointing for calculating coordinates.
        """
        Module.__init__(self, *args, **kwargs)

        # store telescope and pointing
        self._telescope = telescope
        self._pointing = pointing
예제 #12
0
    def __init__(self,
                 camera: Union[str, ICamera],
                 telescope: Union[str, ITelescope],
                 offsets: Union[dict, BaseGuidingOffset],
                 max_offset: float = 30,
                 max_exposure_time: float = None,
                 min_interval: float = 0,
                 max_interval: float = 600,
                 separation_reset: float = None,
                 pid: bool = False,
                 log_file: str = None,
                 *args,
                 **kwargs):
        """Initializes a new science frame auto guiding system.

        Args:
            telescope: Telescope to use.
            offsets: Auto-guider to use
            max_offset: Max offset in arcsec to move.
            max_exposure_time: Maximum exposure time in sec for images to analyse.
            min_interval: Minimum interval in sec between two images.
            max_interval: Maximum interval in sec between to consecutive images to guide.
            separation_reset: Min separation in arcsec between two consecutive images that triggers a reset.
            pid: Whether to use a PID for guiding.
            log_file: Name of file to write log to.
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._camera = camera
        self._telescope = telescope
        self._enabled = False
        self._max_offset = max_offset
        self._max_exposure_time = max_exposure_time
        self._min_interval = min_interval
        self._max_interval = max_interval
        self._separation_reset = separation_reset
        self._pid = pid
        self._loop_closed = False

        # headers of last and of reference image
        self._last_header = None
        self._ref_header = None

        # create auto-guiding system
        self._guiding_offset = get_object(offsets, BaseGuidingOffset)

        # init log file
        self._publisher = None if log_file is None else CsvPublisher(log_file)
예제 #13
0
    def __init__(self, message: str = 'Hello world', interval: int = 10, *args, **kwargs):
        """Creates a new StandAlone object.

        Args:
            message: Message to log in the given interval.
            interval: Interval between messages.
        """
        Module.__init__(self, *args, **kwargs)

        # add thread func
        self._add_thread_func(self._message_func, True)

        # store
        self._message = message
        self._interval = interval
예제 #14
0
    def __init__(self,
                 flatfield: typing.Union[str, IFlatField],
                 functions: typing.Dict[str, str],
                 priorities: typing.Union[dict, SkyflatPriorities],
                 min_exptime: float = 0.5,
                 max_exptime: float = 5,
                 timespan: float = 7200,
                 filter_change: float = 30,
                 count: int = 20,
                 *args,
                 **kwargs):
        """Initialize a new flat field scheduler.

        Args:
            flatfield: Flat field module to use
            functions: Dict with flat functions
            priorities: Class handling priorities
            min_exptime: Minimum exposure time [s]
            max_exptime: Maximum exposure time [s]
            timespan: Time to scheduler after start [s]
            filter_change: Time required for filter change [s]
            count: Number of flats to take per filter/binning
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._flatfield = flatfield
        self._count = count

        # abort
        self._abort = threading.Event()

        # priorities
        prio = get_object(priorities, SkyflatPriorities)

        # create scheduler
        self._scheduler = Scheduler(functions,
                                    prio,
                                    self.observer,
                                    min_exptime=min_exptime,
                                    max_exptime=max_exptime,
                                    timespan=timespan,
                                    filter_change=filter_change,
                                    count=count)
예제 #15
0
    def __init__(self, triggers: list, *args, **kwargs):
        """Initialize a new trigger module.

        Args:
            triggers: List of dictionaries defining the trigger. Must contain fields for event, module and method,
                      may contain a sender.

        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._running = False

        # store triggers and convert event strings to actual classes
        self._triggers = triggers
        for trigger in self._triggers:
            # get class and store it
            kls = get_class_from_string(trigger['event'])
            trigger['event'] = kls
예제 #16
0
    def __init__(self, fits_headers: Optional[Dict[str, Any]] = None, centre: Optional[Tuple[float, float]] = None,
                 rotation: float = 0., flip: bool = False,
                 filenames: str = '/cache/pyobs-{DAY-OBS|date:}-{FRAMENUM|string:04d}-{IMAGETYP|type}00.fits.gz',
                 fits_namespaces: list = None, *args, **kwargs):
        """Creates a new BaseCamera.

        Args:
            fits_headers: Additional FITS headers.
            centre: (x, y) tuple of camera centre.
            rotation: Rotation east of north.
            flip: Whether or not to flip the image along its first axis.
            filenames: Template for file naming.
            fits_namespaces: List of namespaces for FITS headers that this camera should request
        """
        Module.__init__(self, *args, **kwargs)

        # check
        if self.comm is None:
            log.warning('No comm module given, will not be able to signal new images!')

        # store
        self._fits_headers = fits_headers if fits_headers is not None else {}
        if 'OBSERVER' not in self._fits_headers:
            self._fits_headers['OBSERVER'] = ['pyobs', 'Name of observer']
        self._centre = centre
        self._rotation = rotation
        self._flip = flip
        self._filenames = filenames
        self._fits_namespaces = fits_namespaces
        self._exposure_time: float = 0.
        self._image_type = ImageType.OBJECT

        # init camera
        self._exposure: Optional[ExposureInfo] = None
        self._camera_status = ICamera.ExposureStatus.IDLE

        # multi-threading
        self._expose_lock = threading.Lock()
        self.expose_abort = threading.Event()

        # night exposure number
        self._cache = '/pyobs/modules/%s/cache.yaml' % self.name()
        self._frame_num = 0
예제 #17
0
    def __init__(self,
                 tasks: Union[dict, TaskArchive],
                 schedule_range: int = 24,
                 safety_time: int = 60,
                 twilight: str = 'astronomical',
                 *args,
                 **kwargs):
        """Initialize a new scheduler.

        Args:
            scheduler: Scheduler to use
            schedule_range: Number of hours to schedule into the future
            safety_time: If no ETA for next task to start exists (from current task, weather became good, etc), use
                         this time in seconds to make sure that we don't schedule for a time when the scheduler is
                         still running
            twilight: astronomical or nautical
        """
        Module.__init__(self, *args, **kwargs)

        # get scheduler
        self._task_archive = get_object(tasks, TaskArchive)

        # store
        self._schedule_range = schedule_range
        self._safety_time = safety_time
        self._twilight = twilight
        self._running = True
        self._need_update = False

        # time to start next schedule from
        self._schedule_start = None

        # ID of currently running task
        self._current_task_id = None

        # blocks
        self._blocks: List[ObservingBlock] = []
        self._scheduled_blocks: List[ObservingBlock] = []

        # update thread
        self._add_thread_func(self._schedule_thread, True)
        self._add_thread_func(self._update_thread, True)
예제 #18
0
    def __init__(self,
                 filename: str = '/archive/{FNAME}',
                 sources: Union[str, List[str]] = None,
                 *args,
                 **kwargs):
        """Creates a new image writer.

        Args:
            filename: Pattern for filename to store images at.
            sources: List of sources (e.g. cameras) to process images from or None for all.
        """
        Module.__init__(self, *args, **kwargs)

        # add thread func
        self._add_thread_func(self._worker, True)

        # variables
        self._filename = filename
        self._sources = [sources] if isinstance(sources, str) else sources
        self._queue = Queue()
예제 #19
0
    def __init__(self,
                 fits_headers: dict = None,
                 min_altitude: float = 10,
                 wait_for_dome: str = None,
                 *args,
                 **kwargs):
        """Initialize a new base telescope.

        Args:
            fits_headers: Additional FITS headers to send.
            min_altitude: Minimal altitude for telescope.
            wait_for_dome: Name of dome module to wait for.
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._fits_headers = fits_headers if fits_headers is not None else {}
        self._min_altitude = min_altitude

        # some multi-threading stuff
        self._lock_moving = threading.Lock()
        self._abort_move = threading.Event()

        # celestial status
        self._celestial_lock = threading.RLock()
        self._celestial_headers: Dict[str, Any] = {}

        # add thread func
        self._add_thread_func(self._celestial, True)

        # init mixins
        WeatherAwareMixin.__init__(self, *args, **kwargs)
        MotionStatusMixin.__init__(self, *args, **kwargs)
        WaitForMotionMixin.__init__(self,
                                    wait_for_modules=None if
                                    wait_for_dome is None else [wait_for_dome],
                                    wait_for_timeout=60000,
                                    wait_for_states=[
                                        IMotion.Status.POSITIONED,
                                        IMotion.Status.TRACKING
                                    ])
예제 #20
0
    def __init__(self,
                 sources: Union[str, List[str]] = None,
                 publisher: Union[Publisher, dict] = None,
                 max_ellipticity: float = 0.2,
                 correct_for_airmass: bool = True,
                 *args,
                 **kwargs):
        """Creates a new seeing estimator.

        Args:
            sources: List of sources (e.g. cameras) to process images from or None for all.
            publisher: Publisher to publish results to.
            max_ellipticity: Maximum ellipticity for sources to consider.
            correct_for_zenith: Whether to correct seeing for airmass.
        """
        Module.__init__(self, *args, **kwargs)

        # stuff
        self._sources = [sources] if isinstance(sources, str) else sources
        self._publisher = self._add_child_object(publisher, Publisher)
        self._max_ellipticity = max_ellipticity
        self._correct_for_airmass = correct_for_airmass
예제 #21
0
    def __init__(self, focuser: Union[str, IFocuser], camera: Union[str, ICamera], filters: Union[str, IFilters],
                 series: FocusSeries, offset: bool = False, *args, **kwargs):
        """Initialize a new auto focus system.

        Args:
            focuser: Name of IFocuser.
            camera: Name of ICamera.
            filters: Name of IFilters, if any.
            offset: If True, offsets are used instead of absolute focus values.
        """
        Module.__init__(self, *args, **kwargs)

        # store focuser and camera
        self._focuser = focuser
        self._camera = camera
        self._filters = filters
        self._offset = offset
        self._abort = threading.Event()

        # create focus series
        self._series: FocusSeries = get_object(series, FocusSeries)

        # init camera settings mixin
        CameraSettingsMixin.__init__(self, *args, filters=filters, **kwargs)
예제 #22
0
    def __init__(self, tasks: Union[TaskArchive, dict], allowed_overrun: int = 300, *args, **kwargs):
        """Initialize a new auto focus system.

        Args:
            tasks: Task archive to use
            allowed_overrun: Allowed time for a task to exceed it's window in seconds
        """
        Module.__init__(self, *args, **kwargs)

        # store
        self._allowed_overrun = allowed_overrun
        self._running = False

        # add thread func
        self._add_thread_func(self._run_thread, True)

        # get task archive
        self._task_archive: TaskArchive = get_object(tasks, object_class=TaskArchive,
                                                     comm=self.comm, vfs=self.vfs, observer=self.observer)

        # observation name and exposure number
        self._task = None
        self._obs = None
        self._exp = None
예제 #23
0
 def __init__(self, *args, **kwargs):
     """Initialize a new script runner."""
     Module.__init__(self, *args, **kwargs)
예제 #24
0
    def __init__(self,
                 focuser: str = None,
                 weather: str = None,
                 interval: int = 300,
                 temperatures: dict = None,
                 model: str = None,
                 coefficients: dict = None,
                 update: bool = False,
                 log_file: str = None,
                 min_measurements: int = 10,
                 enabled: bool = True,
                 temp_sensor: str = 'average.temp',
                 default_filter: str = None,
                 filter_offsets: dict = None,
                 filter_wheel: str = None,
                 *args,
                 **kwargs):
        """Initialize a focus model.

        Args:
            focuser: Name of focuser.
            weather: Name of weather station.
            interval: Interval for setting focus or None, if no regular setting of focus is required.
            model: Focus model to use.
            coefficients: Coefficients in model, mainly used when updating it.
            update: Whether to update the model on new focus values.
            log_file: Path to file containing all focus measurements.
            min_measurements: Minimum number of measurements to update model.
            enabled: If False, no focus is set.
            temp_sensor: Name of sensor at weather station to provide ambient temperature.
            default_filter: Name of default filter. If None, filters are ignored.
            filter_offsets: Offsets for different filters. If None, they are not modeled.
            filter_wheel: Name of filter wheel module to use for fetching filter before setting focus.
        """
        Module.__init__(self, *args, **kwargs)

        # check import
        import lmfit

        # add thread func
        if interval is not None and interval > 0:
            self._add_thread_func(self._run_thread, True)

        # store
        self._focuser = focuser
        self._weather = weather
        self._interval = interval
        self._temperatures = temperatures = {} if temperatures is None else temperatures
        self._focuser_ready = True
        self._coefficients = {} if coefficients is None else coefficients
        self._update_model = update
        self._min_measurements = min_measurements
        self._enabled = enabled
        self._temp_station, sensor = temp_sensor.split('.')
        self._temp_sensor = IWeather.Sensors(sensor)
        self._default_filter = default_filter
        self._filter_offsets = filter_offsets
        self._filter_wheel = filter_wheel
        log.info('Going to fetch temperature from sensor %s at station %s.',
                 self._temp_sensor, self._temp_station)

        # model
        parser = Parser()
        log.info('Parsing model: %s', model)
        self._model = parser.parse(model)

        # coefficients
        if self._coefficients is not None and len(self._coefficients) > 0:
            log.info(
                'Found coefficients: %s', ', '.join([
                    '%s=%.3f' % (k, v) for k, v in self._coefficients.items()
                ]))

        # variables
        variables = self._model.variables()
        for c in self._coefficients.keys():
            variables.remove(c)
        log.info('Found variables: %s', ', '.join(variables))

        # init log file
        self._publisher = None if log_file is None else CsvPublisher(log_file)

        # update model now?
        if update:
            self._calc_focus_model()