- 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