- Python example addeed
This commit is contained in:
		
							parent
							
								
									a6be70fb7b
								
							
						
					
					
						commit
						dcf7126db3
					
				
							
								
								
									
										138
									
								
								python/runtime/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								python/runtime/main.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
			
		||||
import time
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
sys.path.extend(['/home/epagris/EGYETEM/DIPTERV2/wfr/python/module'])
 | 
			
		||||
 | 
			
		||||
import pywfs
 | 
			
		||||
 | 
			
		||||
import itertools
 | 
			
		||||
import numpy as np
 | 
			
		||||
from matplotlib import pyplot as plt
 | 
			
		||||
from matplotlib import animation as anim
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
# ---------- CONNECT TO AND PREPARE SAMPLING SYSTEM -----------
 | 
			
		||||
 | 
			
		||||
# enable logging onto STDOUT
 | 
			
		||||
pywfs.Logger.start()
 | 
			
		||||
 | 
			
		||||
# discover nodes on the network
 | 
			
		||||
b = pywfs.ServerBeacon()
 | 
			
		||||
b.setInterfaceAddr("10.42.0.1")
 | 
			
		||||
b.singleScan()
 | 
			
		||||
nodes = b.getNodesOnNetwork()
 | 
			
		||||
 | 
			
		||||
# query acquisition format (assume all nodes are identical in this aspect)
 | 
			
		||||
f = b.queryFromNode(nodes[0], "snd acqformat mr")
 | 
			
		||||
acqf = pywfs.AcquisitionFormat(f)
 | 
			
		||||
 | 
			
		||||
# create MSR
 | 
			
		||||
msr = pywfs.MultiStreamReceiver(nodes, f)
 | 
			
		||||
ch_n = msr.getChannelCount()
 | 
			
		||||
 | 
			
		||||
# save samples to file
 | 
			
		||||
# mstf = pywfs.MultiStreamToFile.create("test")
 | 
			
		||||
# msr.listen(mstf)
 | 
			
		||||
 | 
			
		||||
# create oscilloscope data feeder object
 | 
			
		||||
osc = pywfs.MultiStreamOscilloscope.create()
 | 
			
		||||
 | 
			
		||||
# create a slope trigger
 | 
			
		||||
edge_trigger = pywfs.EdgeTrigger()
 | 
			
		||||
edge_trigger.level = 0.2
 | 
			
		||||
edge_trigger.edge = pywfs.FALLING
 | 
			
		||||
 | 
			
		||||
osc.trigger = edge_trigger
 | 
			
		||||
osc.setScreenPeriod(int(20e+06))
 | 
			
		||||
 | 
			
		||||
# start listening for samples
 | 
			
		||||
msr.listen(osc)
 | 
			
		||||
 | 
			
		||||
# enable network sample transmission from every device
 | 
			
		||||
b.execCmdOnAllNodes("snd connect 10.42.0.1 20220")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# # data collection
 | 
			
		||||
# osc.armTrigger()  # arm trigger
 | 
			
		||||
# samples = osc.capture()  # wait for captured data
 | 
			
		||||
#
 | 
			
		||||
# # data collection
 | 
			
		||||
# osc.armTrigger()  # arm trigger
 | 
			
		||||
# samples = osc.capture()  # wait for captured data
 | 
			
		||||
#
 | 
			
		||||
# exit(0)
 | 
			
		||||
 | 
			
		||||
# ------------------ DISPLAY COLLECTED SAMPLES ----------------
 | 
			
		||||
 | 
			
		||||
def data_gen():
 | 
			
		||||
    real_time_last = time.time()
 | 
			
		||||
    index_last = 0
 | 
			
		||||
 | 
			
		||||
    for i in itertools.count():
 | 
			
		||||
        # FPS measurement
 | 
			
		||||
        real_time = time.time()
 | 
			
		||||
        if (real_time - real_time_last) > 1.0:
 | 
			
		||||
            print(i - index_last, " FPS")
 | 
			
		||||
            real_time_last = time.time()
 | 
			
		||||
            index_last = i
 | 
			
		||||
 | 
			
		||||
        # data collection
 | 
			
		||||
        osc.armTrigger()  # arm trigger
 | 
			
		||||
        channels = osc.capture()  # wait for captured data
 | 
			
		||||
 | 
			
		||||
        T = list()
 | 
			
		||||
        Y = list()
 | 
			
		||||
 | 
			
		||||
        for ch in channels:
 | 
			
		||||
            t = list()
 | 
			
		||||
            y_t = list()
 | 
			
		||||
 | 
			
		||||
            for sp in ch:
 | 
			
		||||
                t.append(sp.t * 1E-09)
 | 
			
		||||
                y_t.append(sp.x)
 | 
			
		||||
 | 
			
		||||
            T.append(t)
 | 
			
		||||
            Y.append(y_t)
 | 
			
		||||
 | 
			
		||||
        yield T, Y
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def init():
 | 
			
		||||
    ax.set_ylim(-1.1, 1.1)
 | 
			
		||||
    #ax.set_xlim(-0.01, 0.06)
 | 
			
		||||
 | 
			
		||||
    xlims = osc.getScreenTimeLimits()
 | 
			
		||||
    ax.set_xlim(xlims[0] * 1E-09, xlims[1] * 1E-09)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fig, ax = plt.subplots()
 | 
			
		||||
lines = list()
 | 
			
		||||
 | 
			
		||||
# trigger mark
 | 
			
		||||
screen_period = osc.getScreenPeriod() * 1E-09
 | 
			
		||||
trig_mark_halflen = 0.02
 | 
			
		||||
trig_t = [-trig_mark_halflen * screen_period, trig_mark_halflen * screen_period ]
 | 
			
		||||
trig_y = [ edge_trigger.level, edge_trigger.level ]
 | 
			
		||||
 | 
			
		||||
for k in range(0, ch_n):
 | 
			
		||||
    lines.append(ax.plot([], [], lw=2))
 | 
			
		||||
    t, y = list(), list()
 | 
			
		||||
 | 
			
		||||
ax.plot(trig_t, trig_y, color = 'r')
 | 
			
		||||
 | 
			
		||||
def run(data):
 | 
			
		||||
    T, Y = data
 | 
			
		||||
    for k in range(0, ch_n):
 | 
			
		||||
        lines[k][0].set_data(T[k], Y[k])
 | 
			
		||||
 | 
			
		||||
    return lines[0], lines[1],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ani = anim.FuncAnimation(fig, run, data_gen, interval=20, init_func=init)
 | 
			
		||||
plt.grid()
 | 
			
		||||
plt.show()
 | 
			
		||||
 | 
			
		||||
# disconnect nodes
 | 
			
		||||
b.execCmdOnAllNodes("snd disconnect")
 | 
			
		||||
msr.close()
 | 
			
		||||
							
								
								
									
										129
									
								
								python/setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								python/setup.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from setuptools import Extension, setup
 | 
			
		||||
from setuptools.command.build_ext import build_ext
 | 
			
		||||
 | 
			
		||||
# Convert distutils Windows platform specifiers to CMake -A arguments
 | 
			
		||||
PLAT_TO_CMAKE = {
 | 
			
		||||
    "win32": "Win32",
 | 
			
		||||
    "win-amd64": "x64",
 | 
			
		||||
    "win-arm32": "ARM",
 | 
			
		||||
    "win-arm64": "ARM64",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A CMakeExtension needs a sourcedir instead of a file list.
 | 
			
		||||
# The name must be the _single_ output extension from the CMake build.
 | 
			
		||||
# If you need multiple extensions, see scikit-build.
 | 
			
		||||
class CMakeExtension(Extension):
 | 
			
		||||
    def __init__(self, name, sourcedir=""):
 | 
			
		||||
        Extension.__init__(self, name, sources=[])
 | 
			
		||||
        self.sourcedir = os.path.abspath(sourcedir)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CMakeBuild(build_ext):
 | 
			
		||||
    def build_extension(self, ext):
 | 
			
		||||
        extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
 | 
			
		||||
 | 
			
		||||
        # required for auto-detection & inclusion of auxiliary "native" libs
 | 
			
		||||
        if not extdir.endswith(os.path.sep):
 | 
			
		||||
            extdir += os.path.sep
 | 
			
		||||
 | 
			
		||||
        debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug
 | 
			
		||||
        cfg = "Debug" if debug else "Release"
 | 
			
		||||
 | 
			
		||||
        # CMake lets you override the generator - we need to check this.
 | 
			
		||||
        # Can be set with Conda-Build, for example.
 | 
			
		||||
        cmake_generator = os.environ.get("CMAKE_GENERATOR", "")
 | 
			
		||||
 | 
			
		||||
        # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON
 | 
			
		||||
        # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code
 | 
			
		||||
        # from Python.
 | 
			
		||||
        cmake_args = [
 | 
			
		||||
            f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}",
 | 
			
		||||
            f"-DPYTHON_EXECUTABLE={sys.executable}",
 | 
			
		||||
            f"-DCMAKE_BUILD_TYPE={cfg}",  # not used on MSVC, but no harm
 | 
			
		||||
        ]
 | 
			
		||||
        build_args = []
 | 
			
		||||
        # Adding CMake arguments set as environment variable
 | 
			
		||||
        # (needed e.g. to build for ARM OSx on conda-forge)
 | 
			
		||||
        if "CMAKE_ARGS" in os.environ:
 | 
			
		||||
            cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
 | 
			
		||||
 | 
			
		||||
        # In this example, we pass in the version to C++. You might not need to.
 | 
			
		||||
        cmake_args += [f"-DEXAMPLE_VERSION_INFO={self.distribution.get_version()}"]
 | 
			
		||||
 | 
			
		||||
        if self.compiler.compiler_type != "msvc":
 | 
			
		||||
            # Using Ninja-build since it a) is available as a wheel and b)
 | 
			
		||||
            # multithreads automatically. MSVC would require all variables be
 | 
			
		||||
            # exported for Ninja to pick it up, which is a little tricky to do.
 | 
			
		||||
            # Users can override the generator with CMAKE_GENERATOR in CMake
 | 
			
		||||
            # 3.15+.
 | 
			
		||||
            if not cmake_generator:
 | 
			
		||||
                try:
 | 
			
		||||
                    import ninja  # noqa: F401
 | 
			
		||||
 | 
			
		||||
                    cmake_args += ["-GNinja"]
 | 
			
		||||
                except ImportError:
 | 
			
		||||
                    pass
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
 | 
			
		||||
            # Single config generators are handled "normally"
 | 
			
		||||
            single_config = any(x in cmake_generator for x in {"NMake", "Ninja"})
 | 
			
		||||
 | 
			
		||||
            # CMake allows an arch-in-generator style for backward compatibility
 | 
			
		||||
            contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"})
 | 
			
		||||
 | 
			
		||||
            # Specify the arch if using MSVC generator, but only if it doesn't
 | 
			
		||||
            # contain a backward-compatibility arch spec already in the
 | 
			
		||||
            # generator name.
 | 
			
		||||
            if not single_config and not contains_arch:
 | 
			
		||||
                cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]]
 | 
			
		||||
 | 
			
		||||
            # Multi-config generators have a different way to specify configs
 | 
			
		||||
            if not single_config:
 | 
			
		||||
                cmake_args += [
 | 
			
		||||
                    f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}"
 | 
			
		||||
                ]
 | 
			
		||||
                build_args += ["--config", cfg]
 | 
			
		||||
 | 
			
		||||
        if sys.platform.startswith("darwin"):
 | 
			
		||||
            # Cross-compile support for macOS - respect ARCHFLAGS if set
 | 
			
		||||
            archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
 | 
			
		||||
            if archs:
 | 
			
		||||
                cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))]
 | 
			
		||||
 | 
			
		||||
        # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
 | 
			
		||||
        # across all generators.
 | 
			
		||||
        if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
 | 
			
		||||
            # self.parallel is a Python 3 only way to set parallel jobs by hand
 | 
			
		||||
            # using -j in the build_ext call, not supported by pip or PyPA-build.
 | 
			
		||||
            if hasattr(self, "parallel") and self.parallel:
 | 
			
		||||
                # CMake 3.12+ only.
 | 
			
		||||
                build_args += [f"-j{self.parallel}"]
 | 
			
		||||
 | 
			
		||||
        build_temp = os.path.join(self.build_temp, ext.name)
 | 
			
		||||
        if not os.path.exists(build_temp):
 | 
			
		||||
            os.makedirs(build_temp)
 | 
			
		||||
 | 
			
		||||
        subprocess.check_call(["cmake", ext.sourcedir] + cmake_args, cwd=build_temp)
 | 
			
		||||
        subprocess.check_call(["cmake", "--build", "."] + build_args, cwd=build_temp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The information here can also be placed in setup.cfg - better separation of
 | 
			
		||||
# logic and declaration, and simpler if you include description/version in a file.
 | 
			
		||||
setup(
 | 
			
		||||
    name="WaveFormStrem extension",
 | 
			
		||||
    version="1.0",
 | 
			
		||||
    description="WaveFormStream extension",
 | 
			
		||||
    long_description="",
 | 
			
		||||
    ext_modules=[CMakeExtension("wfr-python")],
 | 
			
		||||
    cmdclass={"build_ext": CMakeBuild},
 | 
			
		||||
    zip_safe=False,
 | 
			
		||||
    extras_require={"test": ["pytest>=6.0"]},
 | 
			
		||||
    python_requires=">=3.6",
 | 
			
		||||
)
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user