-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #183 from slaclab/ESCRYODET-479
Validate the SmurfProcessor's filter
- Loading branch information
Showing
6 changed files
with
465 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#!/usr/bin/env python | ||
#----------------------------------------------------------------------------- | ||
# Title : PySMuRF DataFromFile | ||
#----------------------------------------------------------------------------- | ||
# File : _StreamDataEmulator.py | ||
# Created : 2019-11-15 | ||
#----------------------------------------------------------------------------- | ||
# Description: | ||
# Stream data from a file | ||
#----------------------------------------------------------------------------- | ||
# This file is part of the smurf software platform. It is subject to | ||
# the license terms in the LICENSE.txt file found in the top-level directory | ||
# of this distribution and at: | ||
# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
# No part of the smurf software platform, including this file, may be | ||
# copied, modified, propagated, or distributed except according to the terms | ||
# contained in the LICENSE.txt file. | ||
#----------------------------------------------------------------------------- | ||
|
||
import sys | ||
import time | ||
import rogue.interfaces.stream | ||
import pyrogue | ||
|
||
class DataFromFile(pyrogue.Device): | ||
""" | ||
Class to stream data from a test file. | ||
""" | ||
def __init__(self, name="DataFromFile", description="Data from file source", **kwargs): | ||
pyrogue.Device.__init__(self, name=name, description=description, **kwargs) | ||
self._data_master = DataMaster() | ||
|
||
self.add(pyrogue.LocalVariable( | ||
name='FileName', | ||
description='Path to the data file', | ||
mode='RW', | ||
value='/tmp/fw/x.dat')) | ||
|
||
self.add(pyrogue.LocalVariable( | ||
name='FrameCnt', | ||
description='Number of sent frames', | ||
mode='RO', | ||
value=0, | ||
localGet = self._data_master.get_frame_cnt)) | ||
|
||
self.add(pyrogue.LocalCommand( | ||
name='SendData', | ||
description='Send data', | ||
function=self._send_data)) | ||
|
||
def _send_data(self): | ||
""" | ||
Method to send data from the specified text file. | ||
""" | ||
file_name = self.FileName.get() | ||
self._data_master.send_data(file_name=file_name) | ||
|
||
def _getStreamMaster(self): | ||
""" | ||
Method called by streamConnect, streamTap and streamConnectBiDir to access master. | ||
""" | ||
return self._data_master | ||
|
||
|
||
|
||
class DataMaster(rogue.interfaces.stream.Master): | ||
""" | ||
A Rogue master device, used to stream the data. | ||
""" | ||
def __init__(self): | ||
super().__init__() | ||
self._frame_cnt=0 | ||
|
||
def get_frame_cnt(self): | ||
""" | ||
Get the number of sent frames | ||
""" | ||
return self._frame_cnt | ||
|
||
def send_data(self, file_name): | ||
""" | ||
Send all the data from a text file. The input data file, | ||
must be a text file with data point on each line. The data | ||
must be of type int16. | ||
Each data point is read from the file, and then send on a | ||
frame with the SMuRF header, with only the first channel | ||
containing the data point. | ||
Args: | ||
----- | ||
- file_name (str) : path to the input data file | ||
""" | ||
if not file_name: | ||
print("ERROR: Must define a data file first!") | ||
return | ||
|
||
try: | ||
with open(file_name, 'r') as f: | ||
for data in f: | ||
self.sendData(data=data) | ||
time.sleep(0.01) | ||
|
||
except IOError: | ||
print("Error trying to open {file_name}") | ||
|
||
|
||
# Method for generating a frame | ||
def sendData(self, data): | ||
""" | ||
Send a Rogue Frame. The frame contains the SMuRF header and the | ||
input data point in the first channel. The frame will contain only | ||
one channel. The SMuRF header will be only partially filled, containing | ||
only the number of channels, and a the frame counter words. | ||
Args: | ||
----- | ||
- data (int) : input data (must be of type int16) | ||
""" | ||
|
||
# Request a frame to hold 1 data point | ||
frame = self._reqFrame(128+2, True) | ||
|
||
# Write the number of channels | ||
frame.write( bytearray((1).to_bytes(4, sys.byteorder)), 4) | ||
|
||
# Write the frame counter into the header | ||
frame.write( bytearray(self._frame_cnt.to_bytes(4, sys.byteorder)), 84) | ||
|
||
# Write the data into the first channel | ||
frame.write( bytearray(int(data).to_bytes(2, sys.byteorder, signed=True)), 128) | ||
|
||
# Send the frame | ||
self._sendFrame(frame) | ||
|
||
# Update the frame counter | ||
self._frame_cnt = self._frame_cnt + 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
#!/usr/bin/env python | ||
#----------------------------------------------------------------------------- | ||
# Title : PySMuRF DataToFile | ||
#----------------------------------------------------------------------------- | ||
# File : _StreamDataEmulator.py | ||
# Created : 2019-11-15 | ||
#----------------------------------------------------------------------------- | ||
# Description: | ||
# Receive a stream and write the data to disk | ||
#----------------------------------------------------------------------------- | ||
# This file is part of the smurf software platform. It is subject to | ||
# the license terms in the LICENSE.txt file found in the top-level directory | ||
# of this distribution and at: | ||
# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. | ||
# No part of the smurf software platform, including this file, may be | ||
# copied, modified, propagated, or distributed except according to the terms | ||
# contained in the LICENSE.txt file. | ||
#----------------------------------------------------------------------------- | ||
|
||
import sys | ||
import rogue.interfaces.stream | ||
import pyrogue | ||
|
||
class DataToFile(pyrogue.Device): | ||
""" | ||
Class to write data to a file | ||
""" | ||
def __init__(self, name="DataToFile", description="Data to file writer", **kwargs): | ||
pyrogue.Device.__init__(self, name=name, description=description, **kwargs) | ||
self._data_slave = DataSlave() | ||
self._meta_slave = MetaSlave() | ||
|
||
self.add(pyrogue.LocalVariable( | ||
name='FileName', | ||
description='Path to the data file', | ||
mode='RW', | ||
value='/tmp/fw/y.dat')) | ||
|
||
self.add(pyrogue.LocalCommand( | ||
name='WriteData', | ||
description='Write data to disk', | ||
function=self._write_data)) | ||
|
||
def _write_data(self): | ||
""" | ||
Method to write the data to the specified text file. | ||
""" | ||
file_name = self.FileName.get() | ||
self._data_slave.write_data(file_name=file_name) | ||
|
||
def getDataChannel(self): | ||
""" | ||
Method called by streamConnect, streamTap and streamConnectBiDir to access slave. | ||
This is method is called to request the data channel. | ||
""" | ||
return self._data_slave | ||
|
||
def getMetaChannel(self): | ||
""" | ||
Method called by streamConnect, streamTap and streamConnectBiDir to access slave. | ||
This is method is called to request the metadata channel. | ||
""" | ||
return self._meta_slave | ||
|
||
class DataSlave(rogue.interfaces.stream.Slave): | ||
""" | ||
A Rogue slave device, used receive a stream of data and write it to disk. | ||
""" | ||
def __init__(self): | ||
super().__init__() | ||
self._data = [] | ||
|
||
def write_data(self, file_name): | ||
""" | ||
Method to write the data buffer to a text file. Writes the | ||
content of the data buffer (self._data) to the output file, | ||
one data point on each line as text. | ||
Args: | ||
----- | ||
- file_name (str) : path to the output data file. | ||
""" | ||
if not file_name: | ||
print("ERROR: Must define a data file first!") | ||
return | ||
|
||
try: | ||
with open(file_name, 'w') as f: | ||
for datum in self._data: | ||
f.write(f'{str(datum)}\n') | ||
|
||
|
||
except IOError: | ||
print("Error trying to open {file_name}") | ||
|
||
def _acceptFrame(self, frame): | ||
""" | ||
Args: | ||
Receive a frame with SMuRF data. The first channel is appended | ||
to the data buffer. | ||
----- | ||
frame (rogue.interfaces.stream.Frame) : a frame with SMuRF data. | ||
""" | ||
with frame.lock(): | ||
data = bytearray(4) | ||
|
||
frame.read(data, 128) | ||
self._data.append(int.from_bytes(bytes(data), byteorder=sys.byteorder, signed=True)) | ||
|
||
#try: | ||
# with open(self._file_name, 'a+') as f: | ||
# f.write(f'{str(data_int)}\n') | ||
#except IOError: | ||
# pass | ||
|
||
|
||
class MetaSlave(rogue.interfaces.stream.Slave): | ||
""" | ||
A Rogue slave device, used to connect to the metadata channel. | ||
""" | ||
def __init__(self): | ||
super().__init__() | ||
|
||
def _acceptFrame(self, frame): | ||
""" | ||
Receive a frame with metadata. The frame is discarded. | ||
Args: | ||
----- | ||
frame (rogue.interfaces.stream.Frame) : a frame with metadata | ||
""" | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.