<commit_before>import unittest
import datetime
import tempfile
import shutil
import os

import numpy as np

import astropy.time

import desisurvey.config
import desisurvey.ephem

from desisurvey.test.base import Tester
from surveysim.weather import Weather

class TestWeather(Tester):

    def setUp(self):
        self.w = Weather(seed=123, replay='Y2015')

    def test_dome_open_prob(self):
        """Dome should be (partially) open 26 nights in Dec 2019 when replaying Y2015"""
        n_nights = self.w.num_nights
        self.assertEqual(n_nights, 31)
        open_nights = np.any(self.w._table['open'].reshape(n_nights, -1), axis=1).sum()
        self.assertEqual(open_nights, 26)

    def test_same_seed(self):
        """Weather should be identical with same seed"""
        w = Weather(seed=123, replay='Y2015')
        for name in w._table.colnames:
            self.assertTrue(np.all(self.w._table[name] == w._table[name]))

    def test_different_seed(self):
        """Weather should be different with different seed"""
        w = Weather(seed=1234, replay='Y2015')
        for name in w._table.colnames:
            self.assertTrue(name == 'mjd' or
                            np.any(self.w._table[name] != w._table[name]))

    def test_get(self):
        """The get() method should return nearest time in mjd column"""
        table = self.w._table
        t_step = table['mjd'][1] - table['mjd'][0]
        dt = np.random.uniform(-0.49 * t_step, 0.49 * t_step, size=len(table))
        when = astropy.time.Time(table['mjd'] + dt, format='mjd')
        for i in range(1, len(table) - 1):
            row = self.w.get(when[i])
            self.assertEqual(row['mjd'], table[i]['mjd'])

    def test_get_multiple(self):
        """The get() method can be called with one or multiple times."""
        table = self.w._table
        mjd = table['mjd'][10]
        row = self.w.get(astropy.time.Time(mjd, format='mjd'))
        self.assertTrue(0. <= row['transparency'] <= 1.)
        rows = self.w.get(astropy.time.Time([mjd] * 5, format='mjd'))
        self.assertTrue(len(rows) == 5)
        for i in range(5):
            self.assertTrue(0. <= rows['transparency'][i] <= 1.)

    def test_save_restore(self):
        """Save and restore a weather file"""
        self.w.save('weather.fits')
        w = Weather(restore='weather.fits')
        for name in w._table.colnames:
            self.assertTrue(np.all(self.w._table[name] == w._table[name]))
        self.assertEqual(self.w._table.meta['START'], w._table.meta['START'])
        self.assertEqual(self.w._table.meta['STOP'], w._table.meta['STOP'])
        self.assertEqual(self.w._table.meta['NIGHTS'], w._table.meta['NIGHTS'])
        self.assertEqual(self.w._table.meta['STEPS'], w._table.meta['STEPS'])

def test_suite():
    """Allows testing of only this module with the command::

        python setup.py test -m <modulename>
    """
    return unittest.defaultTestLoader.loadTestsFromName(__name__)
<commit_msg>Clean up imports<commit_after>import unittest

import numpy as np

import astropy.time

import desisurvey.config
import desisurvey.ephem

from desisurvey.test.base import Tester
from surveysim.weather import Weather

class TestWeather(Tester):

    def setUp(self):
        self.w = Weather(seed=123, replay='Y2015')

    def test_dome_open_prob(self):
        """Dome should be (partially) open 26 nights in Dec 2019 when replaying Y2015"""
        n_nights = self.w.num_nights
        self.assertEqual(n_nights, 31)
        open_nights = np.any(self.w._table['open'].reshape(n_nights, -1), axis=1).sum()
        self.assertEqual(open_nights, 26)

    def test_same_seed(self):
        """Weather should be identical with same seed"""
        w = Weather(seed=123, replay='Y2015')
        for name in w._table.colnames:
            self.assertTrue(np.all(self.w._table[name] == w._table[name]))

    def test_different_seed(self):
        """Weather should be different with different seed"""
        w = Weather(seed=1234, replay='Y2015')
        for name in w._table.colnames:
            self.assertTrue(name == 'mjd' or
                            np.any(self.w._table[name] != w._table[name]))

    def test_get(self):
        """The get() method should return nearest time in mjd column"""
        table = self.w._table
        t_step = table['mjd'][1] - table['mjd'][0]
        dt = np.random.uniform(-0.49 * t_step, 0.49 * t_step, size=len(table))
        when = astropy.time.Time(table['mjd'] + dt, format='mjd')
        for i in range(1, len(table) - 1):
            row = self.w.get(when[i])
            self.assertEqual(row['mjd'], table[i]['mjd'])

    def test_get_multiple(self):
        """The get() method can be called with one or multiple times."""
        table = self.w._table
        mjd = table['mjd'][10]
        row = self.w.get(astropy.time.Time(mjd, format='mjd'))
        self.assertTrue(0. <= row['transparency'] <= 1.)
        rows = self.w.get(astropy.time.Time([mjd] * 5, format='mjd'))
        self.assertTrue(len(rows) == 5)
        for i in range(5):
            self.assertTrue(0. <= rows['transparency'][i] <= 1.)

    def test_save_restore(self):
        """Save and restore a weather file"""
        self.w.save('weather.fits')
        w = Weather(restore='weather.fits')
        for name in w._table.colnames:
            self.assertTrue(np.all(self.w._table[name] == w._table[name]))
        self.assertEqual(self.w._table.meta['START'], w._table.meta['START'])
        self.assertEqual(self.w._table.meta['STOP'], w._table.meta['STOP'])
        self.assertEqual(self.w._table.meta['NIGHTS'], w._table.meta['NIGHTS'])
        self.assertEqual(self.w._table.meta['STEPS'], w._table.meta['STEPS'])

def test_suite():
    """Allows testing of only this module with the command::

        python setup.py test -m <modulename>
    """
    return unittest.defaultTestLoader.loadTestsFromName(__name__)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Indicator for Xscreensaver, can be toggled by left clicking.

This is a partial rewrite of dpms.py. Most credit
goes to the original author Andre Doser. This module shows the status
of Xscreensaver and activates or deactivates it upon left click.

This script is useful for people who let Xscreensaver manage dpms
settings. Xscreensaver has its own dpms variables separate from xset.
Dpms can be safely turned off in xset as long as xscreensaver is running.
Settings can be managed using "xscreensaver-demo".

Configuration parameters:
    format_off:    string to display when Xscreensaver is disabled
    format_on:     string to display when Xscreensaver is enabled
    cache_timeout: interval for checking whether Xscreensaver is running
                   (default 30s)

Example configuration in py3status.conf:

```
order += "xscreensaver"
xscreensaver {
    format_off = "xscreensaver off"
    format_on  = "xscreensaver on"
}
```

@author neutronst4r <c7420{at}gmx{dot}net>
"""
from os import setpgrp
from subprocess import call, Popen, DEVNULL
from time import time

class Py3status:
    """
    """
    # available configuration parameters
    format_off = "xscreensaver off"
    format_on = "xscreensaver on"
    color_on = None
    color_off = None
    cache_timeout = 5

    def xscreensaver(self, i3s_output_list, i3s_config):
        """
        Display a colorful state of xscreensaver.
        """
        self.run = call(["pidof", "xscreensaver"],
                        stdout=DEVNULL,
                        stderr=DEVNULL,
                        preexec_fn=setpgrp) == 0
        full_text = self.format_on if self.run else self.format_off
        if self.run:
            color = self.color_on or i3s_config['color_good']
        else:
            color = self.color_off or i3s_config['color_bad']
        return {'full_text': full_text,
                'color': color,
                'cached_until': time() + self.cache_timeout}

    def on_click(self, i3s_output_list, i3s_config, event):
        """
        Enable/Disable xscreensaver on left click.
        """
        if event['button'] == 1:
            if self.run:
                self.run = Popen(["killall", "xscreensaver"],
                                 stdout=DEVNULL,
                                 stderr=DEVNULL,
                                 preexec_fn=setpgrp) == 0
            else:
                self.run = Popen(["xscreensaver",
                                  "-no-splash",
                                  "-no-capture-stderr"],
                                 stdout=DEVNULL,
                                 stderr=DEVNULL,
                                 preexec_fn=setpgrp) == 1

if __name__ == "__main__":
    """
    Test this module by calling it directly.
    """
    from time import sleep
    x = Py3status()
    config = {'color_bad': '#FF0000', 'color_good': '#00FF00', }
    while True:
        print(x.xscreensaver([], config))
        sleep(1)
<commit_msg>add new module: xscreensaver<commit_after># -*- coding: utf-8 -*-
"""
Control Xscreensaver.

This script is useful for people who let Xscreensaver manage DPMS settings.
Xscreensaver has its own DPMS variables separate from xset. DPMS can be
safely turned off in xset as long as Xscreensaver is running.
Settings can be managed using "xscreensaver-demo".

Configuration parameters:
    button_activate: mouse button to activate Xscreensaver (default 3)
    button_toggle: mouse button to toggle Xscreensaver (default 1)
    cache_timeout: refresh interval for this module (default 15)
    format: display format for this module (default '{icon}')
    icon_off: show when Xscreensaver is not running (default 'XSCR')
    icon_on: show when Xscreensaver is running (default 'XSCR')

 Format placeholders:
    {icon} Xscreensaver icon

@author neutronst4r <c7420{at}posteo{dot}net>, lasers
"""

from os import setpgrp
from subprocess import Popen, PIPE

STRING_UNAVAILABLE = "isn't installed"

class Py3status:
    """
    """
    # available configuration parameters
    button_activate = 3
    button_toggle = 1
    cache_timeout = 15
    format = '{icon}'
    icon_off = 'XSCR'
    icon_on = 'XSCR'

    def post_config_hook(self):
        self.color_on = self.py3.COLOR_ON or self.py3.COLOR_GOOD
        self.color_off = self.py3.COLOR_OFF or self.py3.COLOR_BAD
        if not self.py3.check_commands(['xscreensaver']):
            raise Exception(STRING_UNAVAILABLE)

    def _is_running(self):
        try:
            self.py3.command_output(['pidof', 'xscreensaver'])
        except:
            return False
        else:
            return True

    def xscreensaver(self):
        run = self._is_running()
        if run:
            icon = self.icon_on
            color = self.color_on
        else:
            icon = self.icon_off
            color = self.color_off

        return {
            'cached_until': self.py3.time_in(self.cache_timeout),
            'full_text': self.py3.safe_format(self.format, {'icon': icon}),
            'color': color
        }

    def on_click(self, event):
        run = self._is_running()
        if event['button'] == self.button_activate:
            self.py3.command_run(['xscreensaver-command', '-activate'])

        if event['button'] == self.button_toggle:
            if run:
                self.py3.command_run(['xscreensaver-command', '-exit'])
            else:
                # Because we want xscreensaver to continue running after
                # exit, we instead use preexec_fn=setpgrp here.
                Popen(['xscreensaver', '-no-splash', '-no-capture-stderr'],
                      stdout=PIPE, stderr=PIPE, preexec_fn=setpgrp)

if __name__ == "__main__":
    """
    Run module in test mode.
    """
    from py3status.module_test import module_test
    module_test(Py3status)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

import multiprocessing as mp
import numpy as np
import msgpack
import time
from collections import OrderedDict

from .base import DeviceBase

#####
## MultiSignals
def fake_multisignal_mainLoop(stop_flag, stream,  precomputed):
    import zmq
    pos = 0
    abs_pos = pos2 = 0

    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:{}".format(stream['port']))

    socket.send(msgpack.dumps(abs_pos))

    packet_size = stream['packet_size']
    sampling_rate = stream['sampling_rate']
    np_arr = stream['shared_array'].to_numpy_array()
    half_size = np_arr.shape[1]/2
    while True:
        t1 = time.time()
        #~ print 'pos', pos, 'abs_pos', abs_pos
        #double copy
        np_arr[:,pos2:pos2+packet_size] = precomputed[:,pos:pos+packet_size]
        np_arr[:,pos2+half_size:pos2+packet_size+half_size] = precomputed[:,pos:pos+packet_size]
        pos += packet_size
        pos = pos%precomputed.shape[1]
        abs_pos += packet_size
        pos2 = abs_pos%half_size
        socket.send(msgpack.dumps(abs_pos))

        if stop_flag.value:
            print 'will stop'
            break
        t2 = time.time()
        #~ time.sleep(packet_size/sampling_rate-(t2-t1))

        time.sleep(packet_size/sampling_rate)
        #~ gevent.sleep(packet_size/sampling_rate)

class FakeMultiSignals(DeviceBase):
    """
    Usage:
        dev = FakeMultiSignals()
        dev.configure(...)
        dev.initialize()
        dev.start()
        dev.stop()

    Configuration Parameters:
        nb_channel
        sampling_rate
        buffer_length
        packet_size
        channel_names
        channel_indexes

    """
    def __init__(self,  **kargs):
        DeviceBase.__init__(self, **kargs)

    @classmethod
    def get_available_devices(cls):
        devices = OrderedDict()

        for n in [4,8,16, 64]:
            name = 'fake {} analog input'.format(n)
            info = {'board_name' : name,
                        'class' : 'FakeMultiSignals',
                        'global_params' : {
                                                        'sampling_rate' : 1000.,
                                                        'buffer_length' : 60.,
                                                        'packet_size' : 10,
                                                        },
                        'subdevices' : [ {
                                                    'type' : 'AnalogInput',
                                                    'nb_channel' : n,
                                                    'params' :{  },
                                                    'by_channel_params' : {
                                                                            'ai_channel_indexes' : range(n),
                                                                            'ai_channel_names' : [ 'AI Channel {}'.format(i) for i in range(n)],
                                                        },
                                                },
                            ]
                        }
            devices[name] = info

        return devices

    def initialize(self, streamhandler = None):
        self.sampling_rate = float(self.sampling_rate)

        channel_indexes = range(self.nb_channel)
        channel_names = [ 'Channel {}'.format(i) for i in channel_indexes]

        l = int(self.sampling_rate*self.buffer_length)
        self.buffer_length = (l - l%self.packet_size)/self.sampling_rate

        s = self.streamhandler.new_AnalogSignalSharedMemStream(name = self.name, sampling_rate = self.sampling_rate,
                                                        nb_channel = self.nb_channel, buffer_length = self.buffer_length,
                                                        packet_size = self.packet_size, dtype = np.float64,
                                                        channel_names = channel_names, channel_indexes = channel_indexes,
                                                        )

        self.streams = [s, ]

        arr_size = s['shared_array'].shape[1]
        assert (arr_size/2)%self.packet_size ==0, 'buffer should be a multilple of pcket_size {}/2 {}'.format(arr_size, self.packet_size)

        # private precomuted array of 20s = some noise + some sinus burst
        n = int(self.sampling_rate*20./self.packet_size)*self.packet_size
        t = np.arange(n, dtype = np.float64)/self.sampling_rate
        self.precomputed = np.random.rand(self.nb_channel, n)
        for i in range(self.nb_channel):
            f1 = np.linspace(np.random.rand()*60+20. , np.random.rand()*60+20., n)
            f2 = np.linspace(np.random.rand()*1.+.1 , np.random.rand()*1.+.1, n)
            self.precomputed[i,:] += np.sin(2*np.pi*t*f1) * np.sin(np.pi*t*f2+np.random.rand()*np.pi)
            self.precomputed[i,:] += np.random.rand()*40. -20  # add random offset
            self.precomputed[i,:] *= np.random.rand()*10 # add random gain

        print 'FakeMultiAnalogChannel initialized:', self.name, s['port']

    def start(self):

        self.stop_flag = mp.Value('i', 0) #flag pultiproc

        s = self.streams[0]
        mp_arr = s['shared_array'].mp_array
        self.process = mp.Process(target = fake_multisignal_mainLoop,  args=(self.stop_flag, s, self.precomputed) )
        self.process.start()

        print 'FakeMultiAnalogChannel started:', self.name
        self.running = True

    def stop(self):
        self.stop_flag.value = 1
        self.process.join()
        print 'FakeMultiAnalogChannel stopped:', self.name

        self.running = False

    def close(self):
        pass
        #TODO release stream and close the device

#####
## MultiSignals
def fake_digital_mainLoop(stop_flag, stream,  precomputed):
    import zmq
    pos = 0
    abs_pos = pos2 = 0

    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:{}".format(stream['port']))

    packet_size = stream['packet_size']
    sampling_rate = stream['sampling_rate']
    np_arr = stream['shared_array'].to_numpy_array()
    half_size = np_arr.shape[1]/2
    while True:
        t1 = time.time()
        #~ print 'pos', pos, 'abs_pos', abs_pos
        #double copy
        np_arr[:,pos2:pos2+packet_size] = precomputed[:,pos:pos+packet_size]
        np_arr[:,pos2+half_size:pos2+packet_size+half_size] = precomputed[:,pos:pos+packet_size]
        pos += packet_size
        pos = pos%precomputed.shape[1]
        abs_pos += packet_size
        pos2 = abs_pos%half_size
        socket.send(msgpack.dumps(abs_pos))

        if stop_flag.value:
            print 'will stop'
            break
        t2 = time.time()
        #~ time.sleep(packet_size/sampling_rate-(t2-t1))

        time.sleep(packet_size/sampling_rate)
        #~ gevent.sleep(packet_size/sampling_rate)

class FakeDigital(DeviceBase):
    """

    """
    def __init__(self,  **kargs):
        DeviceBase.__init__(self, **kargs)

    @classmethod
    def get_available_devices(cls):
        devices = OrderedDict()

        for n in [8, 32]:
            name = 'fake {} digital input'.format(n)
            info = {'board_name' : name,
                        'class' : 'FakeDigital',
                        'global_params' : {
                                                    'sampling_rate' : 1000.,
                                                    'buffer_length' : 60.,
                                                    'packet_size' : 10,
                                                    },
                        'subdevices' : [ {
                                                    'type' : 'DigitalInput',
                                                    'nb_channel' : n,
                                                    'params' :{ },
                                                    'by_channel_params' : {
                                                                            'di_channel_indexes' : range(n),
                                                                            'di_channel_names' : [ 'DI Channel {}'.format(i) for i in range(n)],
                                                        },
                                                },
                            ]
                        }
            devices[name] = info

        return devices
    def initialize(self, streamhandler = None):
        self.sampling_rate = float(self.sampling_rate)

        channel_names = [ 'Channel {}'.format(i) for i in range(self.nb_channel)]

        l = int(self.sampling_rate*self.buffer_length)
        self.buffer_length = (l - l%self.packet_size)/self.sampling_rate

        s = self.streamhandler.new_DigitalSignalSharedMemStream(name = self.name, sampling_rate = self.sampling_rate,
                                                        nb_channel = self.nb_channel, buffer_length = self.buffer_length,
                                                        packet_size = self.packet_size, channel_names = channel_names)

        self.streams = [s, ]

        arr_size = s['shared_array'].shape[1]
        assert (arr_size/2)%self.packet_size ==0, 'buffer should be a multilple of pcket_size {}/2 {}'.format(arr_size, self.packet_size)

        # private precomuted array of 20s = each channel have a diffrent period
        n = int(self.sampling_rate*20./self.packet_size)*self.packet_size
        t = np.arange(n, dtype = np.float64)/self.sampling_rate
        #~ self.precomputed = np.random.rand(s['shared_array'].shape[0], n)
        self.precomputed = np.zeros((s['shared_array'].shape[0], n), dtype = np.uint8)
        for i in range(self.nb_channel):
            b = i//8
            mask =  1 << i%8

            cycle_size = int((i+1)*self.sampling_rate/2)
            #~ print i, b, mask, cycle_size
            period = np.concatenate([np.ones(cycle_size, dtype = np.uint8), np.zeros(cycle_size, dtype = np.uint8)] * (1+n/cycle_size/2))[:n]
            #~ self.precomputed[b, :period.size] = self.precomputed[b, :period.size] + period*mask
            self.precomputed[b, :] = self.precomputed[b, :] + period*mask
            #~ print (period*mask)[:cycle_size*2]
            #~ print self.precomputed[b,:cycle_size*2]
            #~ print n , period.size
        #~ print 'FakeDigital initialized:', self.name, s['port']

    def start(self):

        self.stop_flag = mp.Value('i', 0) #flag pultiproc

        s = self.streams[0]
        mp_arr = s['shared_array'].mp_array
        self.process = mp.Process(target = fake_digital_mainLoop,  args=(self.stop_flag, s, self.precomputed) )
        self.process.start()

        #~ print 'FakeDigital started:', self.name
        self.running = True

    def stop(self):
        self.stop_flag.value = 1
        self.process.join()
        #~ print 'FakeDigital stopped:', self.name

        self.running = False

    def close(self):
        pass
        #TODO release stream and close the device

<commit_msg>Continue setup.<commit_after># -*- coding: utf-8 -*-

import multiprocessing as mp
import numpy as np
import msgpack
import time
from collections import OrderedDict

from .base import DeviceBase

#####
## MultiSignals
def fake_multisignal_mainLoop(stop_flag, stream,  precomputed):
    import zmq
    pos = 0
    abs_pos = pos2 = 0

    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:{}".format(stream['port']))

    socket.send(msgpack.dumps(abs_pos))

    packet_size = stream['packet_size']
    sampling_rate = stream['sampling_rate']
    np_arr = stream['shared_array'].to_numpy_array()
    half_size = np_arr.shape[1]/2
    while True:
        t1 = time.time()
        #~ print 'pos', pos, 'abs_pos', abs_pos
        #double copy
        np_arr[:,pos2:pos2+packet_size] = precomputed[:,pos:pos+packet_size]
        np_arr[:,pos2+half_size:pos2+packet_size+half_size] = precomputed[:,pos:pos+packet_size]
        pos += packet_size
        pos = pos%precomputed.shape[1]
        abs_pos += packet_size
        pos2 = abs_pos%half_size
        socket.send(msgpack.dumps(abs_pos))

        if stop_flag.value:
            print 'will stop'
            break
        t2 = time.time()
        #~ time.sleep(packet_size/sampling_rate-(t2-t1))

        time.sleep(packet_size/sampling_rate)
        #~ gevent.sleep(packet_size/sampling_rate)

class FakeMultiSignals(DeviceBase):
    """
    Usage:
        dev = FakeMultiSignals()
        dev.configure(...)
        dev.initialize()
        dev.start()
        dev.stop()

    Configuration Parameters:
        nb_channel
        sampling_rate
        buffer_length
        packet_size
        channel_names
        channel_indexes

    """
    def __init__(self,  **kargs):
        DeviceBase.__init__(self, **kargs)

    @classmethod
    def get_available_devices(cls):
        devices = OrderedDict()

        for n in [4,8,16, 64]:
            name = 'fake {} analog input'.format(n)
            info = {'board_name' : name,
                        'class' : 'FakeMultiSignals',
                        'global_params' : {
                                                        'sampling_rate' : 1000.,
                                                        'buffer_length' : 60.,
                                                        'packet_size' : 10,
                                                        'nb_channel' : n,
                                                        },
                        'subdevices' : [ {
                                                    'type' : 'AnalogInput',
                                                    'nb_channel' : n,
                                                    'params' :{  },
                                                    'by_channel_params' : {
                                                                            'ai_channel_indexes' : range(n),
                                                                            'ai_channel_names' : [ 'AI Channel {}'.format(i) for i in range(n)],
                                                        },
                                                },
                            ]
                        }
            devices[name] = info

        return devices

    def initialize(self, streamhandler = None):
        self.sampling_rate = float(self.sampling_rate)

        channel_indexes = range(self.nb_channel)
        channel_names = [ 'Channel {}'.format(i) for i in channel_indexes]

        l = int(self.sampling_rate*self.buffer_length)
        self.buffer_length = (l - l%self.packet_size)/self.sampling_rate

        #FIXME : name
        s = self.streamhandler.new_AnalogSignalSharedMemStream(name = 'yep', sampling_rate = self.sampling_rate,
                                                        nb_channel = self.nb_channel, buffer_length = self.buffer_length,
                                                        packet_size = self.packet_size, dtype = np.float64,
                                                        channel_names = channel_names, channel_indexes = channel_indexes,
                                                        )

        self.streams = [s, ]

        arr_size = s['shared_array'].shape[1]
        assert (arr_size/2)%self.packet_size ==0, 'buffer should be a multilple of pcket_size {}/2 {}'.format(arr_size, self.packet_size)

        # private precomuted array of 20s = some noise + some sinus burst
        n = int(self.sampling_rate*20./self.packet_size)*self.packet_size
        t = np.arange(n, dtype = np.float64)/self.sampling_rate
        self.precomputed = np.random.rand(self.nb_channel, n)
        for i in range(self.nb_channel):
            f1 = np.linspace(np.random.rand()*60+20. , np.random.rand()*60+20., n)
            f2 = np.linspace(np.random.rand()*1.+.1 , np.random.rand()*1.+.1, n)
            self.precomputed[i,:] += np.sin(2*np.pi*t*f1) * np.sin(np.pi*t*f2+np.random.rand()*np.pi)
            self.precomputed[i,:] += np.random.rand()*40. -20  # add random offset
            self.precomputed[i,:] *= np.random.rand()*10 # add random gain

        print 'FakeMultiAnalogChannel initialized:',  s['port']

    def start(self):

        self.stop_flag = mp.Value('i', 0) #flag pultiproc

        s = self.streams[0]
        mp_arr = s['shared_array'].mp_array
        self.process = mp.Process(target = fake_multisignal_mainLoop,  args=(self.stop_flag, s, self.precomputed) )
        self.process.start()

        print 'FakeMultiAnalogChannel started:'
        self.running = True

    def stop(self):
        self.stop_flag.value = 1
        self.process.join()
        print 'FakeMultiAnalogChannel stopped:'

        self.running = False

    def close(self):
        pass
        #TODO release stream and close the device

#####
## MultiSignals
def fake_digital_mainLoop(stop_flag, stream,  precomputed):
    import zmq
    pos = 0
    abs_pos = pos2 = 0

    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:{}".format(stream['port']))

    packet_size = stream['packet_size']
    sampling_rate = stream['sampling_rate']
    np_arr = stream['shared_array'].to_numpy_array()
    half_size = np_arr.shape[1]/2
    while True:
        t1 = time.time()
        #~ print 'pos', pos, 'abs_pos', abs_pos
        #double copy
        np_arr[:,pos2:pos2+packet_size] = precomputed[:,pos:pos+packet_size]
        np_arr[:,pos2+half_size:pos2+packet_size+half_size] = precomputed[:,pos:pos+packet_size]
        pos += packet_size
        pos = pos%precomputed.shape[1]
        abs_pos += packet_size
        pos2 = abs_pos%half_size
        socket.send(msgpack.dumps(abs_pos))

        if stop_flag.value:
            print 'will stop'
            break
        t2 = time.time()
        #~ time.sleep(packet_size/sampling_rate-(t2-t1))

        time.sleep(packet_size/sampling_rate)
        #~ gevent.sleep(packet_size/sampling_rate)

class FakeDigital(DeviceBase):
    """

    """
    def __init__(self,  **kargs):
        DeviceBase.__init__(self, **kargs)

    @classmethod
    def get_available_devices(cls):
        devices = OrderedDict()

        for n in [8, 32]:
            name = 'fake {} digital input'.format(n)
            info = {'board_name' : name,
                        'class' : 'FakeDigital',
                        'global_params' : {
                                                    'sampling_rate' : 1000.,
                                                    'buffer_length' : 60.,
                                                    'packet_size' : 10,
                                                    'nb_channel' : n,
                                                    },
                        'subdevices' : [ {
                                                    'type' : 'DigitalInput',
                                                    'nb_channel' : n,
                                                    'params' :{ },
                                                    'by_channel_params' : {
                                                                            'di_channel_indexes' : range(n),
                                                                            'di_channel_names' : [ 'DI Channel {}'.format(i) for i in range(n)],
                                                        },
                                                },
                            ]
                        }
            devices[name] = info

        return devices
    def initialize(self, streamhandler = None):
        self.sampling_rate = float(self.sampling_rate)

        channel_names = [ 'Channel {}'.format(i) for i in range(self.nb_channel)]

        l = int(self.sampling_rate*self.buffer_length)
        self.buffer_length = (l - l%self.packet_size)/self.sampling_rate

        s = self.streamhandler.new_DigitalSignalSharedMemStream(name = 'yep', sampling_rate = self.sampling_rate,
                                                        nb_channel = self.nb_channel, buffer_length = self.buffer_length,
                                                        packet_size = self.packet_size, channel_names = channel_names)

        self.streams = [s, ]

        arr_size = s['shared_array'].shape[1]
        assert (arr_size/2)%self.packet_size ==0, 'buffer should be a multilple of pcket_size {}/2 {}'.format(arr_size, self.packet_size)

        # private precomuted array of 20s = each channel have a diffrent period
        n = int(self.sampling_rate*20./self.packet_size)*self.packet_size
        t = np.arange(n, dtype = np.float64)/self.sampling_rate
        #~ self.precomputed = np.random.rand(s['shared_array'].shape[0], n)
        self.precomputed = np.zeros((s['shared_array'].shape[0], n), dtype = np.uint8)
        for i in range(self.nb_channel):
            b = i//8
            mask =  1 << i%8

            cycle_size = int((i+1)*self.sampling_rate/2)
            #~ print i, b, mask, cycle_size
            period = np.concatenate([np.ones(cycle_size, dtype = np.uint8), np.zeros(cycle_size, dtype = np.uint8)] * (1+n/cycle_size/2))[:n]
            #~ self.precomputed[b, :period.size] = self.precomputed[b, :period.size] + period*mask
            self.precomputed[b, :] = self.precomputed[b, :] + period*mask
            #~ print (period*mask)[:cycle_size*2]
            #~ print self.precomputed[b,:cycle_size*2]
            #~ print n , period.size
        #~ print 'FakeDigital initialized:', self.name, s['port']

    def start(self):

        self.stop_flag = mp.Value('i', 0) #flag pultiproc

        s = self.streams[0]
        mp_arr = s['shared_array'].mp_array
        self.process = mp.Process(target = fake_digital_mainLoop,  args=(self.stop_flag, s, self.precomputed) )
        self.process.start()

        #~ print 'FakeDigital started:', self.name
        self.running = True

    def stop(self):
        self.stop_flag.value = 1
        self.process.join()
        #~ print 'FakeDigital stopped:', self.name

        self.running = False

    def close(self):
        pass
        #TODO release stream and close the device

<|endoftext|>


<commit_before>import binary_snapshot_io
import os.path

def get_filename(directory, file, snapnum=0, filenum=0):
    if filenum==0 and snapnum==0:
        filename = directory + "/" + file
        if os.path.isfile(filename): return filename

    if filenum==0:
        filename = "%s/%s_%03d" % (directory, file, snapnum)
        if os.path.isfile(filename): return filename

        filename = "%s/snapdir_%03d/%s_%03d" % (directory, snapnum, file, snapnum)
        if os.path.isfile(filename): return filename

    filename = "%s/%s_%03d.%d" % (directory, file, snapnum, filenum)
    if os.path.isfile(filename): return filename

    filename = "%s/snapdir_%03d/%s_%03d.%d" % (directory, snapnum, file, snapnum, filenum)
    if os.path.isfile(filename): return filename

    print "Unable to find Gadget snapshot file %s %s %d %d.\n" % (directory, file, snapnum, filenum)
    raise IOError

def load_snapshot_file(directory, filename, snapshot_num, file_num=0):
    filename = get_filename(directory, filename, snapshot_num, file_num)
    return binary_snapshot_io.read_snapshot_file(filename)

def load_snapshot_files(directory, file, snapshot_num):
    filename = get_filename(directory, file, snapshot_num)

    header = binary_snapshot_io.read_header(filename)
    num_files = header['num_files']

    for i in range(num_files[0]):
        filename = get_filename(directory, file, snapshot_num, i)
        header, res = binary_snapshot_io.read_snapshot_file(filename, False)
        yield header, res
<commit_msg>Updated function call<commit_after>import binary_snapshot_io
import os.path

def get_filename(directory, file, snapnum=0, filenum=0):
    if filenum==0 and snapnum==0:
        filename = directory + "/" + file
        if os.path.isfile(filename): return filename

    if filenum==0:
        filename = "%s/%s_%03d" % (directory, file, snapnum)
        if os.path.isfile(filename): return filename

        filename = "%s/snapdir_%03d/%s_%03d" % (directory, snapnum, file, snapnum)
        if os.path.isfile(filename): return filename

    filename = "%s/%s_%03d.%d" % (directory, file, snapnum, filenum)
    if os.path.isfile(filename): return filename

    filename = "%s/snapdir_%03d/%s_%03d.%d" % (directory, snapnum, file, snapnum, filenum)
    if os.path.isfile(filename): return filename

    print "Unable to find Gadget snapshot file %s %s %d %d.\n" % (directory, file, snapnum, filenum)
    raise IOError

def load_snapshot_file(directory, filename, snapshot_num, file_num=0):
    filename = get_filename(directory, filename, snapshot_num, file_num)
    return binary_snapshot_io.read_snapshot_file(filename)

def load_snapshot_files(directory, file, snapshot_num):
    filename = get_filename(directory, file, snapshot_num)

    header = binary_snapshot_io.read_snapshot_header(filename)
    num_files = header['num_files']

    for i in range(num_files[0]):
        filename = get_filename(directory, file, snapshot_num, i)
        header, res = binary_snapshot_io.read_snapshot_file(filename, False)
        yield header, res
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import unicode_literals

import re

from sqlalchemy.engine import reflection
from sqlalchemy.engine.default import DefaultDialect
from sqlalchemy.sql.compiler import (BIND_PARAMS, BIND_PARAMS_ESC,
                                     IdentifierPreparer, SQLCompiler)
from sqlalchemy.sql.sqltypes import (BIGINT, BINARY, BOOLEAN, DATE, DECIMAL, FLOAT,
                                     INTEGER, NULLTYPE, STRINGTYPE, TIMESTAMP)

import pyathenajdbc

class UniversalSet(object):
    """UniversalSet

    https://github.com/dropbox/PyHive/blob/master/pyhive/common.py"""
    def __contains__(self, item):
        return True

class AthenaIdentifierPreparer(IdentifierPreparer):
    """PrestoIdentifierPreparer

    https://github.com/dropbox/PyHive/blob/master/pyhive/sqlalchemy_presto.py"""
    reserved_words = UniversalSet()

class AthenaCompiler(SQLCompiler):
    """PrestoCompiler

    https://github.com/dropbox/PyHive/blob/master/pyhive/sqlalchemy_presto.py"""
    def visit_char_length_func(self, fn, **kw):
        return 'length{0}'.format(self.function_argspec(fn, **kw))

    def visit_textclause(self, textclause, **kw):
        def do_bindparam(m):
            name = m.group(1)
            if name in textclause._bindparams:
                return self.process(textclause._bindparams[name], **kw)
            else:
                return self.bindparam_string(name, **kw)

        if not self.stack:
            self.isplaintext = True

        if len(textclause._bindparams) == 0:
            # Prevents double escaping of percent character
            return textclause.text
        else:
            # un-escape any \:params
            return BIND_PARAMS_ESC.sub(
                lambda m: m.group(1),
                BIND_PARAMS.sub(
                    do_bindparam,
                    self.post_process_text(textclause.text))
            )

_TYPE_MAPPINGS = {
    'boolean': BOOLEAN,
    'real': FLOAT,
    'float': FLOAT,
    'double': FLOAT,
    'tinyint': INTEGER,
    'smallint': INTEGER,
    'integer': INTEGER,
    'bigint': BIGINT,
    'decimal': DECIMAL,
    'char': STRINGTYPE,
    'varchar': STRINGTYPE,
    'array': STRINGTYPE,
    'row': STRINGTYPE,  # StructType
    'varbinary': BINARY,
    'map': STRINGTYPE,
    'date': DATE,
    'timestamp': TIMESTAMP,
}

class AthenaDialect(DefaultDialect):

    name = 'awsathena'
    driver = 'jdbc'
    preparer = AthenaIdentifierPreparer
    statement_compiler = AthenaCompiler
    default_paramstyle = pyathenajdbc.paramstyle
    supports_alter = False
    supports_pk_autoincrement = False
    supports_default_values = False
    supports_empty_insert = False
    supports_unicode_statements = True
    supports_unicode_binds = True
    returns_unicode_strings = True
    description_encoding = None
    supports_native_boolean = True

    _pattern_column_type = re.compile(r'^([a-zA-Z]+)($|\(.+\)$)')

    @classmethod
    def dbapi(cls):
        return pyathenajdbc

    def _get_default_schema_name(self, connection):
        return connection.connection.schema_name

    def create_connect_args(self, url):
        # Connection string format:
        #   awsathena+jdbc://
        #   {access_key}:{secret_key}@athena.{region_name}.amazonaws.com:443/
        #   {schema_name}?s3_staging_dir={s3_staging_dir}&driver_path={driver_path}&...
        opts = {
            'access_key': url.username if url.username else None,
            'secret_key': url.password if url.password else None,
            'region_name': re.sub(r'^athena\.([a-z0-9-]+)\.amazonaws\.com$', r'\1', url.host),
            'schema_name': url.database if url.database else 'default'
        }
        opts.update(url.query)
        return [[], opts]

    @reflection.cache
    def get_schema_names(self, connection, **kw):
        query = """
                SELECT schema_name
                FROM information_schema.schemata
                WHERE schema_name NOT IN ('information_schema')
                """
        return [row.schema_name for row in connection.execute(query).fetchall()]

    @reflection.cache
    def get_table_names(self, connection, schema=None, **kw):
        schema = schema if schema else connection.connection.schema_name
        query = """
                SELECT table_name
                FROM information_schema.tables
                WHERE table_schema = '{0}'
                """.format(schema)
        return [row.table_name for row in connection.execute(query).fetchall()]

    def has_table(self, connection, table_name, schema=None):
        table_names = self.get_table_names(connection, schema)
        if table_name in table_names:
            return True
        return False

    @reflection.cache
    def get_columns(self, connection, table_name, schema=None, **kw):
        schema = schema if schema else connection.connection.schema_name
        query = """
                SELECT
                  table_schema,
                  table_name,
                  column_name,
                  data_type,
                  is_nullable,
                  column_default,
                  ordinal_position,
                  comment
                FROM information_schema.columns
                WHERE table_schema = '{schema}'
                AND table_name = '{table}'
                """.format(schema=schema, table=table_name)
        return [
            {
                'name': row.column_name,
                'type': _TYPE_MAPPINGS.get(self._get_column_type(row.data_type), NULLTYPE),
                'nullable': True if row.is_nullable == 'YES' else False,
                'default': row.column_default,
                'ordinal_position': row.ordinal_position,
                'comment': row.comment,
            } for row in connection.execute(query).fetchall()
        ]

    def _get_column_type(self, type_):
        return self._pattern_column_type.sub(r'\1', type_)

    def get_foreign_keys(self, connection, table_name, schema=None, **kw):
        # Athena has no support for foreign keys.
        return []

    def get_pk_constraint(self, connection, table_name, schema=None, **kw):
        # Athena has no support for primary keys.
        return []

    def get_indexes(self, connection, table_name, schema=None, **kw):
        # Athena has no support for indexes.
        return []

    def do_rollback(self, dbapi_connection):
        # No transactions for Athena
        pass

    def _check_unicode_returns(self, connection, additional_tests=None):
        # Requests gives back Unicode strings
        return True

    def _check_unicode_description(self, connection):
        # Requests gives back Unicode strings
        return True
<commit_msg>Fix AttributeError: 'Engine' object has no attribute 'connection'<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import unicode_literals

import re

from sqlalchemy.engine import reflection, Engine
from sqlalchemy.engine.default import DefaultDialect
from sqlalchemy.sql.compiler import (BIND_PARAMS, BIND_PARAMS_ESC,
                                     IdentifierPreparer, SQLCompiler)
from sqlalchemy.sql.sqltypes import (BIGINT, BINARY, BOOLEAN, DATE, DECIMAL, FLOAT,
                                     INTEGER, NULLTYPE, STRINGTYPE, TIMESTAMP)

import pyathenajdbc

class UniversalSet(object):
    """UniversalSet

    https://github.com/dropbox/PyHive/blob/master/pyhive/common.py"""
    def __contains__(self, item):
        return True

class AthenaIdentifierPreparer(IdentifierPreparer):
    """PrestoIdentifierPreparer

    https://github.com/dropbox/PyHive/blob/master/pyhive/sqlalchemy_presto.py"""
    reserved_words = UniversalSet()

class AthenaCompiler(SQLCompiler):
    """PrestoCompiler

    https://github.com/dropbox/PyHive/blob/master/pyhive/sqlalchemy_presto.py"""
    def visit_char_length_func(self, fn, **kw):
        return 'length{0}'.format(self.function_argspec(fn, **kw))

    def visit_textclause(self, textclause, **kw):
        def do_bindparam(m):
            name = m.group(1)
            if name in textclause._bindparams:
                return self.process(textclause._bindparams[name], **kw)
            else:
                return self.bindparam_string(name, **kw)

        if not self.stack:
            self.isplaintext = True

        if len(textclause._bindparams) == 0:
            # Prevents double escaping of percent character
            return textclause.text
        else:
            # un-escape any \:params
            return BIND_PARAMS_ESC.sub(
                lambda m: m.group(1),
                BIND_PARAMS.sub(
                    do_bindparam,
                    self.post_process_text(textclause.text))
            )

_TYPE_MAPPINGS = {
    'boolean': BOOLEAN,
    'real': FLOAT,
    'float': FLOAT,
    'double': FLOAT,
    'tinyint': INTEGER,
    'smallint': INTEGER,
    'integer': INTEGER,
    'bigint': BIGINT,
    'decimal': DECIMAL,
    'char': STRINGTYPE,
    'varchar': STRINGTYPE,
    'array': STRINGTYPE,
    'row': STRINGTYPE,  # StructType
    'varbinary': BINARY,
    'map': STRINGTYPE,
    'date': DATE,
    'timestamp': TIMESTAMP,
}

class AthenaDialect(DefaultDialect):

    name = 'awsathena'
    driver = 'jdbc'
    preparer = AthenaIdentifierPreparer
    statement_compiler = AthenaCompiler
    default_paramstyle = pyathenajdbc.paramstyle
    supports_alter = False
    supports_pk_autoincrement = False
    supports_default_values = False
    supports_empty_insert = False
    supports_unicode_statements = True
    supports_unicode_binds = True
    returns_unicode_strings = True
    description_encoding = None
    supports_native_boolean = True

    _pattern_column_type = re.compile(r'^([a-zA-Z]+)($|\(.+\)$)')

    @classmethod
    def dbapi(cls):
        return pyathenajdbc

    def _raw_connection(self, connection):
        if isinstance(connection, Engine):
            return connection.raw_connection()
        return connection.connection

    def create_connect_args(self, url):
        # Connection string format:
        #   awsathena+jdbc://
        #   {access_key}:{secret_key}@athena.{region_name}.amazonaws.com:443/
        #   {schema_name}?s3_staging_dir={s3_staging_dir}&driver_path={driver_path}&...
        opts = {
            'access_key': url.username if url.username else None,
            'secret_key': url.password if url.password else None,
            'region_name': re.sub(r'^athena\.([a-z0-9-]+)\.amazonaws\.com$', r'\1', url.host),
            'schema_name': url.database if url.database else 'default'
        }
        opts.update(url.query)
        return [[], opts]

    @reflection.cache
    def get_schema_names(self, connection, **kw):
        query = """
                SELECT schema_name
                FROM information_schema.schemata
                WHERE schema_name NOT IN ('information_schema')
                """
        return [row.schema_name for row in connection.execute(query).fetchall()]

    @reflection.cache
    def get_table_names(self, connection, schema=None, **kw):
        raw_connection = self._raw_connection(connection)
        schema = schema if schema else raw_connection.schema_name
        query = """
                SELECT table_name
                FROM information_schema.tables
                WHERE table_schema = '{0}'
                """.format(schema)
        return [row.table_name for row in connection.execute(query).fetchall()]

    def has_table(self, connection, table_name, schema=None):
        table_names = self.get_table_names(connection, schema)
        if table_name in table_names:
            return True
        return False

    @reflection.cache
    def get_columns(self, connection, table_name, schema=None, **kw):
        raw_connection = self._raw_connection(connection)
        schema = schema if schema else raw_connection.schema_name
        query = """
                SELECT
                  table_schema,
                  table_name,
                  column_name,
                  data_type,
                  is_nullable,
                  column_default,
                  ordinal_position,
                  comment
                FROM information_schema.columns
                WHERE table_schema = '{schema}'
                AND table_name = '{table}'
                """.format(schema=schema, table=table_name)
        return [
            {
                'name': row.column_name,
                'type': _TYPE_MAPPINGS.get(self._get_column_type(row.data_type), NULLTYPE),
                'nullable': True if row.is_nullable == 'YES' else False,
                'default': row.column_default,
                'ordinal_position': row.ordinal_position,
                'comment': row.comment,
            } for row in connection.execute(query).fetchall()
        ]

    def _get_column_type(self, type_):
        return self._pattern_column_type.sub(r'\1', type_)

    def get_foreign_keys(self, connection, table_name, schema=None, **kw):
        # Athena has no support for foreign keys.
        return []

    def get_pk_constraint(self, connection, table_name, schema=None, **kw):
        # Athena has no support for primary keys.
        return []

    def get_indexes(self, connection, table_name, schema=None, **kw):
        # Athena has no support for indexes.
        return []

    def do_rollback(self, dbapi_connection):
        # No transactions for Athena
        pass

    def _check_unicode_returns(self, connection, additional_tests=None):
        # Requests gives back Unicode strings
        return True

    def _check_unicode_description(self, connection):
        # Requests gives back Unicode strings
        return True
<|endoftext|>


<commit_before>try:
    from indiclient import IndiClient
except:
    print("INDiClient not installed")
import time, sys
from datetime import datetime, timedelta
from PIL import Image, ImageFont, ImageDraw
from astropy.io import fits
from astropy.coordinates import EarthLocation
from astropy.time import Time
import astropy.units as u
import numpy
from shutil import copyfile
import time
import json
from astroplan import Observer

FILENAME_FITS = 'latest.fits'
FILENAME_PNG = 'latest.png'
NIGHT_EXP  = 90
DAY_EXP = 0.00001
DATA_DIR = '/home/pi/images/'
resp = None

def take_exposure(exptime=DAY_EXP, filename=FILENAME_FITS):
    # instantiate the client
    indiclient=IndiClient(exptime, filename)
    # set indi server localhost and port 7624
    indiclient.setServer("localhost",7624)
    # connect to indi server pause for 2 seconds
    if (not(indiclient.connectServer())):
         print("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort())+" - Try to run")
         return False
    time.sleep(1)

    # start endless loop, client works asynchron in background, loop stops after disconnect
    while indiclient.connected:
        time.sleep(1)
    return True

def set_exposure(brecon, currenttime):
    sunrise, sunset = rise_set(brecon, currenttime)
    exp = NIGHT_EXP
    print(sunrise, sunset, currenttime)
    if abs(sunrise - currenttime ) < timedelta(seconds=600) or abs(currenttime -sunset) < timedelta(seconds=600):
        exp = DAY_EXP
    elif abs(sunrise - currenttime) < timedelta(seconds=1800) or abs(currenttime -sunset) < timedelta(seconds=1800):
        exp = NIGHT_EXP/10.
    elif abs(sunrise - currenttime) < timedelta(seconds=5400) or (abs(currenttime -sunset) < timedelta(seconds=5400)):
        exp = NIGHT_EXP/2.
    print("Setting exposure time to %s (%s)" % (exp, sunrise-sunset))
    return exp

def setup():
    location = EarthLocation.from_geodetic(-3.48902*u.deg, 51.9249*u.deg, 300*u.m)
    brecon = Observer(location=location, name="Brecon", timezone="UTC")
    return brecon

def rise_set(brecon, currenttime):
    time = Time(currenttime)
    sunset_tonight = brecon.sun_set_time(time, which='nearest')
    sunrise_tonight = brecon.sun_rise_time(time, which='nearest')
    return (sunrise_tonight.datetime, sunset_tonight.datetime)

def make_image(fitsfile=FILENAME_FITS, pngfile=FILENAME_PNG):
    '''
    Function to read in the FITS file from Oculus.
    - find the 99.5% value
    - Make all values above 99.5% value white
    - Write image array to a PNG
    '''
    data = fits.getdata(fitsfile)
    #data1 = data.reshape(data.shape[0]*data.shape[1])
    max_val = numpy.percentile(data,99.5)
    scaled = data*256./max_val
    new_scaled = numpy.ma.masked_greater(scaled, 255.)
    new_scaled.fill_value=255.
    img_data = new_scaled.filled()
    result = Image.fromarray(img_data.astype(numpy.uint8))
    font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSans.ttf", 24)
    textstamp = 'Brecon Beacons All Sky - %s' % datetime.now().strftime("%Y-%m-%d %H:%M")
    draw = ImageDraw.Draw(result)
    draw.text((10, 10), textstamp, font=font, fill=255)
    result.save(pngfile)
    return

def make_json(now=datetime.now()):
    nowtimestamp = datetime.strftime(now,"%a, %d %b %Y %H:%M:%S GMT+0000")
    latestdata = {'time' : nowtimestamp}
    latestjson = json.dumps(latestdata)
    filename = '%slatest.json' % (DATA_DIR)
    f = open(filename,'wb')
    f.write(latestjson)
    f.close()
    return

if __name__ == '__main__':
    brecon = setup()
    currenttime = datetime.utcnow()
    if brecon.is_night(currenttime):
        exp = set_exposure(brecon, currenttime)
        now = datetime.utcnow()
        datestamp = now.strftime("%Y%m%d-%H%M")
        fitsfile = '%s%s' % (DATA_DIR, FILENAME_FITS)
        pngfile = '%s%s.png' % (DATA_DIR, datestamp)
        latestpng = '%slatest.png' % (DATA_DIR)
        resp = take_exposure(exptime=exp, filename=fitsfile)
        if resp:
            make_image(fitsfile=fitsfile, pngfile=pngfile)
            copyfile(pngfile,latestpng)
            make_json(now)
            print("Saved %s - %s" % (pngfile, datetime.utcnow().isoformat()))
        else:
            print("Error!")
    else:
        print("Currently day - %s" % datetime.utcnow().isoformat())
<commit_msg>only import bits of numpy we need<commit_after>try:
    from indiclient import IndiClient
except:
    print("INDiClient not installed")
import time, sys
from datetime import datetime, timedelta
from PIL import Image, ImageFont, ImageDraw
from astropy.io import fits
from astropy.coordinates import EarthLocation
from astropy.time import Time
import astropy.units as u
from numpy import ma, percentile, uint8
from shutil import copyfile
import time
import json
from astroplan import Observer

FILENAME_FITS = 'latest.fits'
FILENAME_PNG = 'latest.png'
NIGHT_EXP  = 90
DAY_EXP = 0.00001
DATA_DIR = '/home/pi/images/'
resp = None

def take_exposure(exptime=DAY_EXP, filename=FILENAME_FITS):
    # instantiate the client
    indiclient=IndiClient(exptime, filename)
    # set indi server localhost and port 7624
    indiclient.setServer("localhost",7624)
    # connect to indi server pause for 2 seconds
    if (not(indiclient.connectServer())):
         print("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort())+" - Try to run")
         return False
    time.sleep(1)

    # start endless loop, client works asynchron in background, loop stops after disconnect
    while indiclient.connected:
        time.sleep(1)
    return True

def set_exposure(brecon, currenttime):
    sunrise, sunset = rise_set(brecon, currenttime)
    exp = NIGHT_EXP
    print(sunrise, sunset, currenttime)
    if abs(sunrise - currenttime ) < timedelta(seconds=600) or abs(currenttime -sunset) < timedelta(seconds=600):
        exp = DAY_EXP
    elif abs(sunrise - currenttime) < timedelta(seconds=1800) or abs(currenttime -sunset) < timedelta(seconds=1800):
        exp = NIGHT_EXP/10.
    elif abs(sunrise - currenttime) < timedelta(seconds=5400) or (abs(currenttime -sunset) < timedelta(seconds=5400)):
        exp = NIGHT_EXP/2.
    print("Setting exposure time to %s (%s)" % (exp, sunrise-sunset))
    return exp

def setup():
    location = EarthLocation.from_geodetic(-3.48902*u.deg, 51.9249*u.deg, 300*u.m)
    brecon = Observer(location=location, name="Brecon", timezone="UTC")
    return brecon

def rise_set(brecon, currenttime):
    time = Time(currenttime)
    sunset_tonight = brecon.sun_set_time(time, which='nearest')
    sunrise_tonight = brecon.sun_rise_time(time, which='nearest')
    return (sunrise_tonight.datetime, sunset_tonight.datetime)

def make_image(fitsfile=FILENAME_FITS, pngfile=FILENAME_PNG):
    '''
    Function to read in the FITS file from Oculus.
    - find the 99.5% value
    - Make all values above 99.5% value white
    - Write image array to a PNG
    '''
    data = fits.getdata(fitsfile)
    #data1 = data.reshape(data.shape[0]*data.shape[1])
    max_val = percentile(data,99.5)
    scaled = data*256./max_val
    new_scaled = ma.masked_greater(scaled, 255.)
    new_scaled.fill_value=255.
    img_data = new_scaled.filled()
    result = Image.fromarray(img_data.astype(uint8))
    font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSans.ttf", 24)
    textstamp = 'Brecon Beacons All Sky - %s' % datetime.now().strftime("%Y-%m-%d %H:%M")
    draw = ImageDraw.Draw(result)
    draw.text((10, 10), textstamp, font=font, fill=255)
    result.save(pngfile)
    return

def make_json(now=datetime.now()):
    nowtimestamp = datetime.strftime(now,"%a, %d %b %Y %H:%M:%S GMT+0000")
    latestdata = {'time' : nowtimestamp}
    latestjson = json.dumps(latestdata)
    filename = '%slatest.json' % (DATA_DIR)
    f = open(filename,'wb')
    f.write(latestjson)
    f.close()
    return

if __name__ == '__main__':
    brecon = setup()
    currenttime = datetime.utcnow()
    if brecon.is_night(currenttime):
        exp = set_exposure(brecon, currenttime)
        now = datetime.utcnow()
        datestamp = now.strftime("%Y%m%d-%H%M")
        fitsfile = '%s%s' % (DATA_DIR, FILENAME_FITS)
        pngfile = '%s%s.png' % (DATA_DIR, datestamp)
        latestpng = '%slatest.png' % (DATA_DIR)
        resp = take_exposure(exptime=exp, filename=fitsfile)
        if resp:
            make_image(fitsfile=fitsfile, pngfile=pngfile)
            copyfile(pngfile,latestpng)
            make_json(now)
            print("Saved %s - %s" % (pngfile, datetime.utcnow().isoformat()))
        else:
            print("Error!")
    else:
        print("Currently day - %s" % datetime.utcnow().isoformat())
<|endoftext|>


<commit_before>''' Helper functions for the unittests are defined here.
'''

import numpy as np
import tables as tb

def get_array_differences(first_array, second_array):
    '''Takes two numpy.ndarrays and compares them on a column basis.
    Different column data types, missing columns and columns with different values are returned in a string.

    Parameters
    ----------
    first_array : numpy.ndarray
    second_array : numpy.ndarray

    Returns
    -------
    string
    '''
    if first_array.dtype.names is None:  # normal nd.array
        return ': Sum first array: ' + str(np.sum(first_array)) + ', Sum second array: ' + str(np.sum(second_array))
    else:
        return_str = ''
        for column_name in first_array.dtype.names:
            first_column = first_array[column_name]
            try:
                second_column = second_array[column_name]
            except ValueError:
                return_str += 'No ' + column_name + ' column found. '
                continue
            if (first_column.dtype != second_column.dtype):
                return_str += 'Column ' + column_name + ' has different data type. '
            try:
                if not (first_column == second_column).all():  # check if the data of the column is equal
                    return_str += 'Column ' + column_name + ' not equal. '
            except AttributeError:
                if not (first_column == second_column):
                    return_str += 'Column ' + column_name + ' not equal. '
        for column_name in second_array.dtype.names:
            try:
                first_array[column_name]
            except ValueError:
                return_str += 'Additional column ' + column_name + ' found. '
                continue
        return ': ' + return_str

def array_close(array_1, array_2, rtol=1.e-5, atol=1.e-8):
    '''Compares two numpy arrays elementwise for similarity with small differences.'''
    if not array_1.dtype.names:
        try:
            return np.allclose(array_1, array_2, rtol=1.e-5, atol=1.e-8, equal_nan=True)  # Only works on non recarrays
        except ValueError:  # Raised if shape is incompatible
            return False
    results = []
    for column in array_1.dtype.names:
        results.append(np.allclose(array_1[column], array_2[column], rtol=1.e-5, atol=1.e-8))
    return np.all(results)

def compare_h5_files(first_file, second_file, node_names=None, detailed_comparison=True, exact=True, rtol=1.e-5, atol=1.e-8, chunk_size=1000000):
    '''Takes two hdf5 files and check for equality of all nodes.
    Returns true if the node data is equal and the number of nodes is the number of expected nodes.
    It also returns a error string containing the names of the nodes that are not equal.

    Parameters
    ----------
    first_file : string
        Path to the first file.
    second_file : string
        Path to the second file.
    node_names : list, tuple
        Iterable of node names that are required to exist and will be compared.
        If None, compare all existing nodes and fail if nodes are not existing.
    detailed_comparison : boolean
        Print reason why the comparison failed
    exact : boolean
        True if the results have to match exactly. E.g. False for fit results.
    rtol, atol: number
        From numpy.allclose:
        rtol : float
            The relative tolerance parameter (see Notes).
        atol : float
            The absolute tolerance parameter (see Notes).

    Returns
    -------
    (bool, string)
    '''
    checks_passed = True
    error_msg = ""
    with tb.open_file(first_file, 'r') as first_h5_file:
        with tb.open_file(second_file, 'r') as second_h5_file:
            fist_file_nodes = [node.name for node in first_h5_file.root]  # get node names
            second_file_nodes = [node.name for node in second_h5_file.root]  # get node names
            if node_names is None:
                additional_first_file_nodes = set(fist_file_nodes) - set(second_file_nodes)
                additional_second_file_nodes = set(second_file_nodes) - set(fist_file_nodes)
                if additional_first_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s has additional nodes: %s\n' % (first_file, ', '.join(additional_first_file_nodes))
                if additional_second_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s has additional nodes: %s\n' % (second_file, ', '.join(additional_second_file_nodes))
                common_nodes = set(fist_file_nodes) & set(second_file_nodes)
            else:
                missing_first_file_nodes = set(node_names) - set(fist_file_nodes)
                if missing_first_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s is missing nodes: %s\n' % (first_file, ', '.join(missing_first_file_nodes))
                missing_second_file_nodes = set(node_names) - set(second_file_nodes)
                if missing_second_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s is missing nodes: %s\n' % (second_file, ', '.join(missing_second_file_nodes))
                common_nodes = (set(fist_file_nodes) & set(second_file_nodes)) & set(node_names)
            for node_name in common_nodes:  # loop over all nodes and compare each node, do not abort if one node is wrong
                nrows = first_h5_file.get_node(first_h5_file.root, node_name).nrows
                index_start = 0
                while index_start < nrows:
                    index_stop = index_start + chunk_size
                    first_file_data = second_h5_file.get_node(second_h5_file.root, node_name).read(index_start, index_stop)
                    second_file_data = second_h5_file.get_node(second_h5_file.root, node_name).read(index_start, index_stop)
                    if exact:
                        try:
                            np.testing.assert_array_equal(first_file_data, second_file_data)
                        except AssertionError as e:
                            checks_passed = False
                            error_msg += node_name
                            if detailed_comparison:
                                error_msg += get_array_differences(first_file_data, second_file_data)
                                error_msg += str(e)
                            error_msg += '\n'
                            break
                    else:
                        if not array_close(first_file_data, second_file_data, rtol, atol):
                            checks_passed = False
                            error_msg += node_name
                            if detailed_comparison:
                                error_msg += get_array_differences(first_file_data, second_file_data)
                            error_msg += '\n'
                            break
                    index_start += chunk_size
    return checks_passed, error_msg
<commit_msg>REG: fix h5 file compare<commit_after>''' Helper functions for the unittests are defined here.
'''

import numpy as np
import tables as tb

def get_array_differences(first_array, second_array):
    '''Takes two numpy.ndarrays and compares them on a column basis.
    Different column data types, missing columns and columns with different values are returned in a string.

    Parameters
    ----------
    first_array : numpy.ndarray
    second_array : numpy.ndarray

    Returns
    -------
    string
    '''
    if first_array.dtype.names is None:  # normal nd.array
        return ': Sum first array: ' + str(np.sum(first_array)) + ', Sum second array: ' + str(np.sum(second_array))
    else:
        return_str = ''
        for column_name in first_array.dtype.names:
            first_column = first_array[column_name]
            try:
                second_column = second_array[column_name]
            except ValueError:
                return_str += 'No ' + column_name + ' column found. '
                continue
            if (first_column.dtype != second_column.dtype):
                return_str += 'Column ' + column_name + ' has different data type. '
            try:
                if not (first_column == second_column).all():  # check if the data of the column is equal
                    return_str += 'Column ' + column_name + ' not equal. '
            except AttributeError:
                if not (first_column == second_column):
                    return_str += 'Column ' + column_name + ' not equal. '
        for column_name in second_array.dtype.names:
            try:
                first_array[column_name]
            except ValueError:
                return_str += 'Additional column ' + column_name + ' found. '
                continue
        return ': ' + return_str

def array_close(array_1, array_2, rtol=1.e-5, atol=1.e-8):
    '''Compares two numpy arrays elementwise for similarity with small differences.'''
    if not array_1.dtype.names:
        try:
            return np.allclose(array_1, array_2, rtol=1.e-5, atol=1.e-8, equal_nan=True)  # Only works on non recarrays
        except ValueError:  # Raised if shape is incompatible
            return False
    results = []
    for column in array_1.dtype.names:
        results.append(np.allclose(array_1[column], array_2[column], rtol=1.e-5, atol=1.e-8))
    return np.all(results)

def compare_h5_files(first_file, second_file, node_names=None, detailed_comparison=True, exact=True, rtol=1.e-5, atol=1.e-8, chunk_size=1000000):
    '''Takes two hdf5 files and check for equality of all nodes.
    Returns true if the node data is equal and the number of nodes is the number of expected nodes.
    It also returns a error string containing the names of the nodes that are not equal.

    Parameters
    ----------
    first_file : string
        Path to the first file.
    second_file : string
        Path to the second file.
    node_names : list, tuple
        Iterable of node names that are required to exist and will be compared.
        If None, compare all existing nodes and fail if nodes are not existing.
    detailed_comparison : boolean
        Print reason why the comparison failed
    exact : boolean
        True if the results have to match exactly. E.g. False for fit results.
    rtol, atol: number
        From numpy.allclose:
        rtol : float
            The relative tolerance parameter (see Notes).
        atol : float
            The absolute tolerance parameter (see Notes).

    Returns
    -------
    (bool, string)
    '''
    checks_passed = True
    error_msg = ""
    with tb.open_file(first_file, 'r') as first_h5_file:
        with tb.open_file(second_file, 'r') as second_h5_file:
            fist_file_nodes = [node.name for node in first_h5_file.root]  # get node names
            second_file_nodes = [node.name for node in second_h5_file.root]  # get node names
            if node_names is None:
                additional_first_file_nodes = set(fist_file_nodes) - set(second_file_nodes)
                additional_second_file_nodes = set(second_file_nodes) - set(fist_file_nodes)
                if additional_first_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s has additional nodes: %s\n' % (first_file, ', '.join(additional_first_file_nodes))
                if additional_second_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s has additional nodes: %s\n' % (second_file, ', '.join(additional_second_file_nodes))
                common_nodes = set(fist_file_nodes) & set(second_file_nodes)
            else:
                missing_first_file_nodes = set(node_names) - set(fist_file_nodes)
                if missing_first_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s is missing nodes: %s\n' % (first_file, ', '.join(missing_first_file_nodes))
                missing_second_file_nodes = set(node_names) - set(second_file_nodes)
                if missing_second_file_nodes:
                    checks_passed = False
                    error_msg += 'File %s is missing nodes: %s\n' % (second_file, ', '.join(missing_second_file_nodes))
                common_nodes = (set(fist_file_nodes) & set(second_file_nodes)) & set(node_names)
            for node_name in common_nodes:  # loop over all nodes and compare each node, do not abort if one node is wrong
                nrows = first_h5_file.get_node(first_h5_file.root, node_name).nrows
                index_start = 0
                while index_start < nrows:
                    index_stop = index_start + chunk_size
                    first_file_data = first_h5_file.get_node(first_h5_file.root, node_name).read(index_start, index_stop)
                    second_file_data = second_h5_file.get_node(second_h5_file.root, node_name).read(index_start, index_stop)
                    if exact:
                        try:
                            np.testing.assert_array_equal(first_file_data, second_file_data)
                        except AssertionError as e:
                            checks_passed = False
                            error_msg += node_name
                            if detailed_comparison:
                                error_msg += get_array_differences(first_file_data, second_file_data)
                                error_msg += str(e)
                            error_msg += '\n'
                            break
                    else:
                        if not array_close(first_file_data, second_file_data, rtol, atol):
                            checks_passed = False
                            error_msg += node_name
                            if detailed_comparison:
                                error_msg += get_array_differences(first_file_data, second_file_data)
                            error_msg += '\n'
                            break
                    index_start += chunk_size
    return checks_passed, error_msg
<|endoftext|>


<commit_before>from landmark_extractor.extraction.Landmark import Rule, RuleSet, flattenResult

def extract(html, url, extractionrulesall, threshold=0.5):
    inferlink_extraction = dict()
    extractionrules = None
    number_of_rules = 0
    matched_rule_key = None
    for rule_key in extractionrulesall.keys():
        if rule_key in url:
            extractionrules = extractionrulesall[rule_key]
            number_of_rules = len(extractionrules)
            matched_rule_key = rule_key
            break

    try:
        rules = RuleSet(extractionrules)
        if rules is not None:
            extraction_list = rules.extract(html)
            flatten = flattenResult(extraction_list)
            if flatten:
                if "posts" in flatten:
                    # this is a forum kind of page, handle differently
                    if len(flatten['posts']) > 0:
                        return flatten['posts']
                else:
                    for key in flatten.keys():
                        if flatten[key].strip() != '':
                            inferlink_extraction[key] = flatten[key]
        properly_extracted_fields = len(inferlink_extraction)
        if properly_extracted_fields > 0 and float(properly_extracted_fields) / float(number_of_rules) >= threshold:
            # print 'rules  %s succeeded for  %s' % (matched_rule_key, url)
            # print '%s rules matched out of %s' % (properly_extracted_fields, number_of_rules)
            # print inferlink_extraction
            return inferlink_extraction
        else:
            # if matched_rule_key:
            #     print 'rules  %s failed for  %s' % (matched_rule_key, url)
            #     print '%s rules matched out of %s' % (properly_extracted_fields, number_of_rules)
            return None
    except Exception, e:
        print "ERRROR:", str(e)
    return None<commit_msg>read rules from the new format allowing multiple rule sets for same tld<commit_after>from landmark_extractor.extraction.Landmark import Rule, RuleSet, flattenResult

def extract(html, url, extractionrulesall, threshold=0.5):
    inferlink_extraction = dict()
    extractionrules_list = None
    number_of_rules = 0
    matched_rule_key = None
    for rule_key in extractionrulesall.keys():
        if rule_key in url:
            extractionrules_list = extractionrulesall[rule_key]
            number_of_rules = len(extractionrules_list)
            matched_rule_key = rule_key
            break

    try:
        if extractionrules_list:
            for extractionrules_obj in extractionrules_list:
                extractionrules = extractionrules_obj['rules']
                rules = RuleSet(extractionrules)
                if rules is not None:
                    extraction_list = rules.extract(html)
                    flatten = flattenResult(extraction_list)
                    if flatten:
                        if "posts" in flatten:
                            # this is a forum kind of page, handle differently
                            if len(flatten['posts']) > 0:
                                return flatten['posts']
                        else:
                            for key in flatten.keys():
                                if flatten[key].strip() != '':
                                    inferlink_extraction[key] = flatten[key]
                properly_extracted_fields = len(inferlink_extraction)
                if properly_extracted_fields > 0 and float(properly_extracted_fields) / float(number_of_rules) >= threshold:
                    # print 'rules  %s succeeded for  %s' % (matched_rule_key, url)
                    # print '%s rules matched out of %s' % (properly_extracted_fields, number_of_rules)
                    # print inferlink_extraction
                    return inferlink_extraction
                else:
                    # if matched_rule_key:
                    #     print 'rules  %s failed for  %s' % (matched_rule_key, url)
                    #     print '%s rules matched out of %s' % (properly_extracted_fields, number_of_rules)
                    return None
    except Exception, e:
        print "ERRROR:", str(e)
    return None<|endoftext|>


<commit_before>from indiclient import IndiClient
import time, sys
from datetime import datetime, timedelta
import ephem as eph
from PIL import Image
from astropy.io import fits
import numpy
from shutil import copyfile

FILENAME_FITS = 'latest.fits'
FILENAME_PNG = 'latest.png'
NIGHT_EXP  = 120
DAY_EXP = 0.00001
DATA_DIR = '/home/pi/images/'
resp = None

def take_exposure(exptime=DAY_EXP, filename=FILENAME_FITS):
    # instantiate the client
    indiclient=IndiClient(exptime, filename)
    # set indi server localhost and port 7624
    indiclient.setServer("localhost",7624)
    # connect to indi server pause for 2 seconds
    if (not(indiclient.connectServer())):
         print("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort())+" - Try to run")
         return False
    time.sleep(1)

    # start endless loop, client works asynchron in background, loop stops after disconnect
    while indiclient.connected:
        time.sleep(1)
    return True

def set_exposure(currenttime):
    sunrise, sunset = rise_set(currenttime)
    if (sunrise-sunset) < timedelta(days=1):
        exp = NIGHT_EXP
    else:
        exp = DAY_EXP
    print("Setting exposure time to %s (%s)" % (exp, sunrise-sunset))
    return exp

def rise_set(currenttime=None):
    brecon = eph.Observer()
    brecon.lat, brecon.lon = '51.924854', '-3.488342'
    brecon.date = currenttime.strftime('%Y/%m/%d %H:%M') if not currenttime else datetime.utcnow()
    sunrise_eph = brecon.next_rising(eph.Sun()).tuple()
    sunset_eph = brecon.previous_setting(eph.Sun()).tuple()
    sunrise = datetime(*sunrise_eph[0:-1])
    sunset = datetime(*sunset_eph[0:-1])
    return (sunrise, sunset)

def make_image(fitsfile=FILENAME_FITS, pngfile=FILENAME_PNG):
    data = fits.getdata(fitsfile)
    data1 = data.reshape(data.shape[0]*data.shape[1])
    hist, edges = numpy.histogram(data1,200)
    min_val = edges[1]
    scaled = data*1024./(data.max() - min_val)
    result = Image.fromarray(scaled.astype(numpy.uint8))
    result.save(pngfile)
    return

if __name__ == '__main__':
    currenttime = datetime.utcnow()
    exp = set_exposure(currenttime)
    datestamp = datetime.now().strftime("%Y%m%d-%H%M")
    fitsfile = '%s%s' % (DATA_DIR, FILENAME_FITS)
    pngfile = '%s%s.png' % (DATA_DIR, datestamp)
    latestpng = '%slatest.png' % (DATA_DIR)
    if exp == NIGHT_EXP:
        resp = take_exposure(exptime=exp, filename=fitsfile)
    if resp:
        make_image(fitsfile=fitsfile, pngfile=pngfile)
        copyfile(pngfile,latestpng)
        print("Saved %s" % pngfile)
<commit_msg>Working image maker with 99.5% scaling<commit_after>from indiclient import IndiClient
import time, sys
from datetime import datetime, timedelta
import ephem as eph
from PIL import Image
from astropy.io import fits
import numpy
from shutil import copyfile

FILENAME_FITS = 'latest.fits'
FILENAME_PNG = 'latest.png'
NIGHT_EXP  = 120
DAY_EXP = 0.00001
DATA_DIR = '/home/pi/images/'
resp = None

def take_exposure(exptime=DAY_EXP, filename=FILENAME_FITS):
    # instantiate the client
    indiclient=IndiClient(exptime, filename)
    # set indi server localhost and port 7624
    indiclient.setServer("localhost",7624)
    # connect to indi server pause for 2 seconds
    if (not(indiclient.connectServer())):
         print("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort())+" - Try to run")
         return False
    time.sleep(1)

    # start endless loop, client works asynchron in background, loop stops after disconnect
    while indiclient.connected:
        time.sleep(1)
    return True

def set_exposure(currenttime):
    sunrise, sunset = rise_set(currenttime)
    if (sunrise-sunset) < timedelta(days=1):
        exp = NIGHT_EXP
    else:
        exp = DAY_EXP
    print("Setting exposure time to %s (%s)" % (exp, sunrise-sunset))
    return exp

def rise_set(currenttime=None):
    brecon = eph.Observer()
    brecon.lat, brecon.lon = '51.924854', '-3.488342'
    brecon.date = currenttime.strftime('%Y/%m/%d %H:%M') if not currenttime else datetime.utcnow()
    sunrise_eph = brecon.next_rising(eph.Sun()).tuple()
    sunset_eph = brecon.previous_setting(eph.Sun()).tuple()
    sunrise = datetime(*sunrise_eph[0:-1])
    sunset = datetime(*sunset_eph[0:-1])
    return (sunrise, sunset)

def make_image(fitsfile=FILENAME_FITS, pngfile=FILENAME_PNG):
    '''
    Function to read in the FITS file from Oculus.
    - flatten the 2D image array to 1D and find the 99.5% value
    - Make all values above 99.5% value white
    - Write image array to a PNG
    '''
    data = fits.getdata(fitsfile)
    data1 = data.reshape(data.shape[0]*data.shape[1])
    max_val = numpy.percentile(data1,99.5)
    scaled = data*256./max_val
    new_scaled = ma.masked_greater(scaled, 255.)
    new_scaled.fill_value=255.
    img_data = new_scaled.filled()
    result = Image.fromarray(img_data.astype(numpy.uint8))
    result.save(pngfile)
    return

if __name__ == '__main__':
    currenttime = datetime.utcnow()
    exp = set_exposure(currenttime)
    datestamp = datetime.now().strftime("%Y%m%d-%H%M")
    fitsfile = '%s%s' % (DATA_DIR, FILENAME_FITS)
    pngfile = '%s%s.png' % (DATA_DIR, datestamp)
    latestpng = '%slatest.png' % (DATA_DIR)
    if exp == NIGHT_EXP:
        resp = take_exposure(exptime=exp, filename=fitsfile)
    if resp:
        make_image(fitsfile=fitsfile, pngfile=pngfile)
        copyfile(pngfile,latestpng)
        print("Saved %s" % pngfile)
<|endoftext|>