コード例 #1
0
ファイル: main_window.py プロジェクト: nanoepics/pynta
    def __init__(self, refresh_time=30):
        super().__init__()
        uic.loadUi(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'designer', 'MainWindow.ui'), self)
        self.logger = get_logger(name=__name__)

        self.central_layout = QHBoxLayout(self.centralwidget)
        self.widget_splitter = QSplitter()

        self.camera_viewer_widget = CameraViewerWidget()
        self.histogram_tracks_widget = HistogramTracksWidget(self)
        self.widget_splitter.addWidget(self.camera_viewer_widget)
        self.widget_splitter.addWidget(self.histogram_tracks_widget)
        self.widget_splitter.setSizes((750, 750))
        self.central_layout.addWidget(self.widget_splitter)

        self.config_widget = ConfigWidget()
        self.config_tracking_widget = ConfigTrackingWidget()


        self.refresh_timer = QTimer()
        self.refresh_timer.timeout.connect(self.update_gui)
        self.refresh_timer.start(refresh_time)

        self.showMaximized()

        self.connect_actions()
        self.connect_buttons()
        self.connect_signals()
コード例 #2
0
ファイル: __main__.py プロジェクト: nanoepics/pynta
def main():
    logger = get_logger(
    )  # 'nanoparticle_tracking.model.experiment.nanoparticle_tracking.saver'
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    parser = ArgumentParser(description='Start the pyNTA software')
    parser.add_argument("-c",
                        dest="config_file",
                        required=False,
                        help="Path to the configuration file")
    args = parser.parse_args()

    if args.config_file is None:
        config_file = os.path.join(BASE_DIR, 'util', 'example_config.yml')
    else:
        config_file = args.config_file
    exp = NPTracking(config_file)
    exp.initialize_camera()
    app = QApplication([])
    window = MainWindow(exp)
    window.show()
    app.exec()
コード例 #3
0
ファイル: publisher.py プロジェクト: JulianMuenzberg/pynta
def publisher(queue, event, port):
    """ Simple method that starts a publisher on the port 5555.

    :param multiprocessing.Queue queue: Queue of messages to be broadcasted
    :param multiprocessing.Event event: Event to stop the publisher
    :param int port: port in which to broadcast data
    .. TODO:: The publisher's port should be determined in a configuration file.
    """
    logger = get_logger(name=__name__)
    port_pub = port
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:%s" % port_pub)
    sleep(1)  # It takes a time for subscribers to propagate to the publisher.
    # Without this sleep the first packages may be lost
    logger.info('Bound socket on {}'.format(port_pub))
    while not event.is_set():
        while not queue.empty():
            data = queue.get(
            )  # Should be a dictionary {'topic': topic, 'data': data}
            logger.debug('Sending {} on {}'.format(data['data'],
                                                   data['topic']))
            socket.send_string(data['topic'], zmq.SNDMORE)
            socket.send_pyobj(data['data'])
            if general_stop_event.is_set():
                break
        sleep(0.05)  # Sleeps 5 milliseconds to be polite with the CPU

    sleep(1)  # Gives enough time to the subscribers to update their status
    socket.close()
    logger.info('Stopped the publisher')
コード例 #4
0
ファイル: publisher.py プロジェクト: JulianMuenzberg/pynta
 def __init__(self, port=5555):
     self.logger = get_logger(name=__name__)
     self._port = port
     self._queue = Queue(
     )  # The publisher will grab and broadcast the messages from this queue
     self._event = Event()  # This event is used to stop the process
     self._process = Process(target=publisher,
                             args=[self._queue, self._event, self._port])
     self.logger.info('Initialized published on port {}'.format(port))
コード例 #5
0
ファイル: decorators.py プロジェクト: JulianMuenzberg/pynta
 def func_wrapper(*args, **kwargs):
     logger = get_logger(name=__name__)
     logger.info('Starting a new thread for {}'.format(func.__name__))
     args[0]._processes.append(
         [func.__name__,
          Process(target=func, args=args, kwargs=kwargs)])
     args[0]._processes[-1][1].start()
     logger.debug('In total there are {} processes'.format(
         len(args[0]._threads)))
コード例 #6
0
ファイル: base_camera.py プロジェクト: nanoepics/pynta
    def __init__(self, camera):
        self.camera = camera
        self.running = False
        self.max_width = 0
        self.max_height = 0
        self.exposure = 0
        self.config = {}
        self.data_type = np.uint16  # The data type that the camera generates when acquiring images. It is very important to have it available in order to create the buffer and saving to disk.

        self.logger = get_logger(name=__name__)
コード例 #7
0
ファイル: publisher.py プロジェクト: kailiu77/pynta
 def __init__(self, port=None):
     self.logger = get_logger(name=__name__)
     if not port:
         self._port = config.zmq_port
     else:
         self._port = port
     self._queue = Queue(
     )  # The publisher will grab and broadcast the messages from this queue
     self._event = Event()  # This event is used to stop the process
     self._process = None
     self.logger.info('Initialized publisher on port {}'.format(self._port))
コード例 #8
0
    def __init__(self, camera):
        super().__init__(camera)

        self.running = False
        self.xsize = 1080
        self.ysize = 720
        self.sb = SimBrownian((self.xsize, self.ysize))
        self.maxX = 1800
        self.maxY = 720
        self.exposure = Q_('10ms')
        self.X = [0, self.maxX-1]
        self.Y = [0, self.maxY-1]
        self.logger = get_logger(name=__name__)
コード例 #9
0
def worker_listener(file_path, meta, topic, port=5555, max_memory=500):
    """ Function that listens on the specified port for new data and then saves it to disk. It is the same as
    :func:`worker_saver` but implementing a ZMQ socket instead of grabbing data from a queue.

    :param str file_path: the path to the file to use.
    :param str meta: Metadata. It is kept as a string in order to provide flexibility for other programs.
    :param int port: Port on which to listen for publisher data
    :param int max_memory: Maximum memory (in MB) to allocate
    """
    logger = get_logger(name=__name__)
    logger.info('Starting worker saver for topic {} on port {}'.format(
        topic, port))
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect("tcp://localhost:{}".format(port))
    topic_filter = topic.encode('ascii')
    socket.setsockopt(zmq.SUBSCRIBE, topic_filter)
    allocate_memory = max_memory  # megabytes of memory to allocate on the hard drive.

    with h5py.File(file_path, "a") as f:
        now = str(datetime.now())
        g = f.create_group(now)
        g.create_dataset('metadata', data=meta.encode("ascii", "ignore"))
        # Has to be submitted via the socket a string 'stop'

        i = 0
        j = 0
        first = True

        while True:
            topic = socket.recv_string()
            data = socket.recv_pyobj()
            logger.debug('Got data of type {} on the saver topic {}.'.format(
                type(data), topic))
            if isinstance(data, str):
                logger.info('Got the signal to stop the saving')
                break
            data = data[1]
            if first:  # First time it runs, creates the dataset
                x = data.shape[0]
                y = data.shape[1]
                logger.debug('Image size: {}x{}'.format(x, y))
                allocate = int(allocate_memory / data.nbytes * 1024 * 1024)
                logger.debug('Allocating {}MB to stream to disk'.format(
                    allocate_memory))
                logger.debug('Allocate {} frames'.format(allocate))
                d = np.zeros((x, y, allocate), dtype=data.dtype)
                dset = g.create_dataset(
                    'timelapse', (x, y, allocate),
                    maxshape=(x, y, None),
                    compression='gzip',
                    compression_opts=1,
                    dtype=data.dtype
                )  # The images are going to be stacked along the z-axis.
                d[:, :, i] = data
                i += 1
                first = False
            else:
                if i == allocate:
                    logger.debug('Allocating more memory')
                    dset[:, :, j:j + allocate] = d
                    dset.resize((x, y, j + 2 * allocate))
                    d = np.zeros((x, y, allocate), dtype=data.dtype)
                    i = 0
                    j += allocate
                d[:, :, i] = data
                i += 1

        if j > 0 or i > 0:
            logger.info('Saving last bits of data before stopping.')
            logger.debug('Missing values: {}'.format(i))
            dset[:, :, j:j + i] = d[:, :, :i]  # Last save before closing

        # This last bit is to avoid having a lot of zeros at the end of the timelapses
        dset.resize((x, y, j + i))

        logger.info('Flushing file to disk...')
        f.flush()
        logger.info('Finished writing to disk')
コード例 #10
0
def worker_saver(file_path, meta, q, max_memory=500):
    """Function that can be run in a separate thread for continuously save data to disk.

    :param str file_path: the path to the file to use.
    :param str meta: Metadata. It is kept as a string in order to provide flexibility for other programs.
    :param Queue q: Queue that will store all the images to be saved to disk.
    :param int max_memory: Maximum memory (in MB) to allocate
    """
    logger = get_logger(name=__name__)
    logger.info('Appending data to {}'.format(file_path))
    allocate_memory = max_memory  # megabytes of memory to allocate on the hard drive.

    with h5py.File(file_path, "a") as f:
        now = str(datetime.now())
        g = f.create_group(now)
        g.create_dataset('metadata', data=meta.encode("ascii", "ignore"))
        keep_saving = True  # Flag that will stop the worker function if running in a separate thread.
        # Has to be submitted via the queue a string 'exit'

        i = 0
        j = 0
        first = True

        while keep_saving:
            while not q.empty() or q.qsize() > 0:
                img = q.get()
                if isinstance(img, str):
                    keep_saving = False
                    logger.info('Got the signal to stop the saving')
                    continue

                if first:  # First time it runs, creates the dataset
                    x = img.shape[0]
                    y = img.shape[1]
                    logger.debug('Image size: {}x{}'.format(x, y))
                    allocate = int(allocate_memory / img.nbytes * 1024 * 1024)
                    logger.debug('Allocating {}MB to stream to disk'.format(
                        allocate_memory))
                    logger.debug('Allocate {} frames'.format(allocate))
                    d = np.zeros((x, y, allocate), dtype=img.dtype)
                    dset = g.create_dataset(
                        'timelapse', (x, y, allocate),
                        maxshape=(x, y, None),
                        compression='gzip',
                        compression_opts=1,
                        dtype=img.dtype
                    )  # The images are going to be stacked along the z-axis.
                    d[:, :, i] = img
                    i += 1
                    first = False
                else:
                    if i == allocate:
                        logger.debug('Allocating more memory')
                        dset[:, :, j:j + allocate] = d
                        dset.resize((x, y, j + 2 * allocate))
                        d = np.zeros((x, y, allocate), dtype=img.dtype)
                        i = 0
                        j += allocate
                    d[:, :, i] = img
                    i += 1

        if j > 0 or i > 0:
            logger.info('Saving last bits of data before stopping.')
            logger.debug('Missing values: {}'.format(i))
            dset[:, :, j:j + i] = d[:, :, :i]  # Last save before closing

        # This last bit is to avoid having a lot of zeros at the end of the timelapses
        dset.resize((x, y, j + i))

        logger.info('Flushing file to disk...')
        f.flush()
    logger.info('Finished writing to disk')
コード例 #11
0
ファイル: base_camera.py プロジェクト: nanoepics/pynta
    is very important for the GUI, since after the first crop, if the user wants to crop even further, the information
    has to be referenced to the already cropped area.


    .. note:: **IMPORTANT** Whatever new function is implemented in a specific model, it should be first declared in the BaseCamera class. In this way the other models will have access to the method and the program will keep running (perhaps with non intended behavior though).

    :copyright:  Aquiles Carattino <*****@*****.**>
    :license: GPLv3, see LICENSE for more details
"""
import numpy as np

from pynta.model.cameras.decorators import not_implemented
from pynta.util.log import get_logger
from pynta import Q_

logger = get_logger(__name__)


class BaseCamera:
    MODE_CONTINUOUS = 1
    MODE_SINGLE_SHOT = 0
    ACQUISITION_MODE = {
        MODE_CONTINUOUS: 'Continuous',
        MODE_SINGLE_SHOT: 'Single'
    }

    def __init__(self, camera):
        self.camera = camera
        self.running = False
        self.max_width = 0
        self.max_height = 0
コード例 #12
0
import logging
from time import sleep

from pynta.model.experiment.nanoparticle_tracking.np_tracking import NPTracking
from pynta.util.log import get_logger

logger = get_logger(
)  # 'nanoparticle_tracking.model.experiment.nanoparticle_tracking.saver'
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

if __name__ == '__main__':
    with NPTracking('config/nanocet.yml') as exp:
        sleep(1)
        # exp.connect(calculate_positions_image, 'free_run', exp.publisher_queue, **exp.config['tracking']['locate'])
        # exp.connect(add_to_save_queue, 'free_run', exp.saver_queue)
        # exp.connect(add_linking_queue, 'trackpy_locations', exp.locations_queue)
        # exp.connect(add_links_to_queue, 'particle_links', exp.tracks_queue)
        exp.initialize_camera()
        # exp.link_particles()
        exp.save_stream()
        sleep(1)
        exp.start_free_run()
        logger.info('Going to sleep for 5 seconds')
        sleep(5)
        logger.info('Keep acquiring set to false')
コード例 #13
0
    Base model for communicating with Arduino devices. In principle, Arduino's can be programmed in very different
    ways, and therefore the flow of information may be very different. This model is thought to interface with
    an Arduino which is in control of two DC motors and which is able to read values from some devices, such as a
    DHT22, and a DS18B20. It relies on PyVisa with pyvisa-py as backend in order to establish the communication with the
    device.
"""
from time import sleep

import pyvisa
from pynta.util.log import get_logger
# TODO: Make more flexible which backend will be used for PyVisa
from pynta.model.exceptions import OutOfRange

rm = pyvisa.ResourceManager('@py')
logger = get_logger(name=__name__)


class Arduino:
    def __init__(self, port=None):
        """

        :param port: Serial port where the Arduino is connected, can be none and in order to look for devices
        automatically
        """
        logger.info(f'Starting Arduino class on port {port}')
        self.rsc = None
        self.port = port
        if port:
            if not port.startswith('ASRL'):
                port = 'ASRL' + port
コード例 #14
0
ファイル: main_window.py プロジェクト: nanoepics/pynta
    def update_tracking_config(self, config):
        self.logger.error('Update Tracking config method not defined')

    def update_config(self, config):
        self.logger.error('Update Config method not defined')

    def closeEvent(self, *args, **kwargs):
        self.config_widget.close()
        self.config_tracking_widget.close()
        super(MainWindowGUI, self).closeEvent(*args, **kwargs)


if __name__ == "__main__":
    import sys
    import logging
    from PyQt5.QtWidgets import QApplication

    logger = get_logger(name=__name__)
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    app = QApplication([])
    win = MainWindowGUI()
    win.show()
    sys.exit(app.exec_())
コード例 #15
0
ファイル: publisher.py プロジェクト: JulianMuenzberg/pynta
            )  # Should be a dictionary {'topic': topic, 'data': data}
            logger.debug('Sending {} on {}'.format(data['data'],
                                                   data['topic']))
            socket.send_string(data['topic'], zmq.SNDMORE)
            socket.send_pyobj(data['data'])
            if general_stop_event.is_set():
                break
        sleep(0.05)  # Sleeps 5 milliseconds to be polite with the CPU

    sleep(1)  # Gives enough time to the subscribers to update their status
    socket.close()
    logger.info('Stopped the publisher')


if __name__ == "__main__":
    logger = get_logger(
        name=__name__)  # 'pynta.model.experiment.nano_cet.saver'
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    p = Publisher()
    p.start()
    p.publish('Testing', [1, 2, 3, 4])
    sleep(1)
    p.stop()
    p.join()
コード例 #16
0
import logging
from time import sleep

from pynta.model.experiment.nano_cet.win_nanocet import NanoCET
from pynta.util.log import get_logger

logger = get_logger()  # 'pynta.model.experiment.nano_cet.saver'
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

if __name__ == '__main__':
    with NanoCET('config/nanocet.yml') as exp:
        sleep(1)
        # exp.connect(calculate_positions_image, 'free_run', exp.publisher_queue, **exp.config['tracking']['locate'])
        # exp.connect(add_to_save_queue, 'free_run', exp.saver_queue)
        # exp.connect(add_linking_queue, 'trackpy_locations', exp.locations_queue)
        # exp.connect(add_links_to_queue, 'particle_links', exp.tracks_queue)
        exp.initialize_camera()
        # exp.link_particles()
        exp.save_stream()
        sleep(1)
        exp.start_free_run()
        logger.info('Going to sleep for 5 seconds')
        sleep(5)
        logger.info('Keep acquiring set to false')
        exp.keep_acquiring = False