musst.py 3.33 KB
Newer Older
1
2
3
4
5
6
7
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.

8
from ..chain import AcquisitionDevice, AcquisitionChannel
9
from bliss.common.event import dispatcher
Matias Guijarro's avatar
Matias Guijarro committed
10
import gevent
11
from gevent import event
12
import numpy
Matias Guijarro's avatar
Matias Guijarro committed
13
14

class MusstAcquisitionDevice(AcquisitionDevice):
15
16
  def __init__(self, musst_dev,
               program=None,
17
18
               store_list=None, vars=None,
               program_template_replacement=None):
19
20
21
22
23
24
25
26
    """
    Acquisition device for the musst card.

    program -- the program you need to load for your scan
    program_template_replacement -- substitution variable before sending it to the card
    store_list -- a list of variable you store in musst memory during the scan
    vars -- all variable you want to set before the musst program starts
    """
27
    AcquisitionDevice.__init__(self, musst_dev, "musst", "zerod", trigger_type=AcquisitionDevice.HARDWARE)
Matias Guijarro's avatar
Matias Guijarro committed
28
    self.musst = musst_dev
29
    self.program = program
30
31
32
33
34
35
    if program_template_replacement is not None:
      self.program_template_replacement = program_template_replacement
    else:
      self.program_template_replacement = dict()
    self.vars = vars if vars is not None else dict()
    store_list = store_list if store_list is not None else list()
36
    self.channels.extend((AcquisitionChannel(name,numpy.int32, (1,)) for name in store_list))
Matias Guijarro's avatar
Matias Guijarro committed
37

38
39
    self.next_vars = None
    self._iter_index = 0
40
41
42
    self._ready_flag = True
    self._ready_event = event.Event()

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  def __iter__(self):
    if isinstance(self.vars,(list,tuple)):
      vars_iter = iter(self.vars)
      while True:
        self.next_vars = vars_iter.next()
        yield self
        self._iter_index += 1
    else:
      self.next_vars = self.vars
      self._iter_index = 0
      while True:
        yield self
        self._iter_index += 1
        
  def prepare(self):
    if self._iter_index == 0:
      self.musst.upload_file(self.program,
                             template_replacement=self.program_template_replacement)

    for var_name, value in self.next_vars.iteritems():	
63
      self.musst.putget("VAR %s %s" %  (var_name,value))
64
65
    self._ready_flag = True
    
Matias Guijarro's avatar
Matias Guijarro committed
66
  def start(self):
67
    self.musst.run()
Matias Guijarro's avatar
Matias Guijarro committed
68

69
70
71
  def stop(self):
    self.musst.ABORT

72
73
74
75
76
  def wait_ready(self):
    while not self._ready_flag:
      self._ready_event.wait()
      self._ready_event.clear()
      
77
  def reading(self):
Matias Guijarro's avatar
Matias Guijarro committed
78
    last_read_event = 0
79
80
81
82
83
84
85
86
87
88
89
90
91
    try:
      while self.musst.STATE == self.musst.RUN_STATE:
        new_read_event = self._send_data(last_read_event)
        if new_read_event != last_read_event:
          last_read_event = new_read_event
          gevent.sleep(100e-6)   # be able to ABORT the musst card
        else:
          gevent.sleep(10e-3)   # relax a little bit.
      self._send_data(last_read_event) # final send
    finally:
      self._ready_flag = True
      self._ready_event.set()
      
92
93
94
95
96
97
98
99
100
  def _send_data(self,last_read_event):
      data = self.musst.get_data(len(self.channels),last_read_event)
      if data.size > 0:
        channel_data = dict(zip((c.name for c in self.channels), [data[:,i] for i in range(len(self.channels))]))
        dispatcher.send("new_data", self, { "channel_data": channel_data })
        nb_event_read = data.shape[0]
        last_read_event += nb_event_read
      return last_read_event

Matias Guijarro's avatar
Matias Guijarro committed
101