123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- from PyQt4 import QtCore, QtGui
- from ..base import kcgwidget as kcgw
- from ..base.globals import glob as global_objects
- from ..base.backend import board
- from ..base.backend.board import available_boards
- from .. import config
- import pyqtgraph as pg
- from math import ceil
- import numpy as np
- import socket
- <<<<<<< HEAD
- import sys
- =======
- >>>>>>> da4c26e... Added ethernet socket to FrequencyExtractWidget
- from .PlotWidget import SubPlotWidget
- __widget_id__ = None
- class FrequencyExtractWidget(kcgw.KCGWidgets):
- def __init__(self, unique_id, parent):
- super(FrequencyExtractWidget, self).__init__()
- self.id = unique_id
- self.par = parent
-
- #ToDo: Maybe find valid data from the get-go?
- self.data = None
- self.board_config = board.get_board_config(available_boards[0])
- self.board_config.observe(self, self.dataSetChanged, 'lastDataSet')
- self.numADCs = self.board_config.get('adc_number')
- #Use a VBox. Top half should be the SubPlotWidget, bottom
- #half should be the controls
- self.layout = QtGui.QVBoxLayout()
-
- self.plotBox = QtGui.QVBoxLayout()
- self.plot = SubPlotWidget()
- self.region = pg.LinearRegionItem(values=[10,20])
- self.plot.plotItem.addItem(self.region)
- self.region.sigRegionChangeFinished.connect(self.doPlot)
- self.line = pg.InfiniteLine(angle=0, label='Y={value:0.2f}',
- labelOpts={'movable': True})
- self.plot.plotItem.addItem(self.line)
- self.line.hide()
- self.plotBox.addWidget(self.plot)
- #Controls for the plot
- self.controlsBox = QtGui.QHBoxLayout()
- self.adcSelect = QtGui.QComboBox(self)
- for i in range(self.numADCs):
- self.adcSelect.addItem("ADC {}".format(i+1))
- self.adcSelect.currentIndexChanged.connect(self.doPlot)
- self.bucketSelect = QtGui.QComboBox(self)
- self.bucketSelect.addItem("Mean")
- for i in range(184):
- self.bucketSelect.addItem("Bucket {}".format(i+1))
- self.bucketSelect.currentIndexChanged.connect(self.doPlot)
- self.fromBox = self.createSpinbox(0, 100000000, interval=100, connect=self.doPlot)
- self.toBox = self.createSpinbox(0, 100000000, start_value=1000, interval=100, connect=self.doPlot)
- self.controlsBox.addWidget(self.adcSelect)
- self.controlsBox.addWidget(self.bucketSelect)
- self.controlsBox.addStretch()
- self.controlsBox.addWidget(self.createLabel(text="From:"))
- self.controlsBox.addWidget(self.fromBox)
- self.controlsBox.addWidget(self.createLabel(text="To:"))
- self.controlsBox.addWidget(self.toBox)
- self.frequencyTools = QtGui.QHBoxLayout()
-
- self.freqText = QtGui.QLineEdit(self)
- self.isFreqValid = False
- self.frequencyTools.addWidget(self.createLabel(text="Frequency:"))
- self.frequencyTools.addWidget(self.freqText)
- self.ethernetControls = QtGui.QHBoxLayout()
- self.ethernetControls.addWidget(self.createLabel("IP:"))
- self.ip = QtGui.QLineEdit(self)
- self.ethernetControls.addWidget(self.ip)
- self.ethernetControls.addWidget(self.createLabel("Port:"))
- self.port = self.createSpinbox(1024, 65535)
- self.port.setValue(56000)
- self.ethernetControls.addWidget(self.port)
- self.ethButton = self.createButton("Connect", connect=self.connectEthernet)
- self.ethernetControls.addWidget(self.ethButton)
- self.socketConnected = False
- self.layout.addLayout(self.plotBox)
- self.layout.addLayout(self.controlsBox)
- self.layout.addLayout(self.frequencyTools)
- self.layout.addLayout(self.ethernetControls)
- self.setLayout(self.layout)
- self.setWindowTitle("Frequency Extract")
- def connectEthernet(self):
- if not self.socketConnected:
- #closing the socket also frees the underlying File-Descriptor,
- #so we need to create a new socket every time we want to create
- #a new connection
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- socket.inet_aton(self.ip.text())
- except OSError:
- print("Malformed IP: %s"%self.ip.text())
- return
- try:
- self.socket.connect((self.ip.text(), self.port.value()))
- self.socketConnected = True
- self.ethButton.setText("Disconnect")
- except:
- print("Failed to connect to %s"%self.ip.text())
- self.socket = None
- else:
- self.socket.close()
- self.socketConnected = False
- self.ethButton.setText("Connect")
- def sendFreqEth(self, freq):
- if not self.socketConnected:
- return
- #We work in the kHz domain
- freq /= 1000
- offset = 10
- step = 0.08
- max = (offset + (step * 127))
-
- if (freq > max) or (freq < offset):
- print("Frequency outside range: %.2fkhZ - %.2fkHz! Won't send..."%(offset,max))
- return
- tmp = freq - offset - step
- count = 0
- while tmp > 0:
- tmp -= step
- count += 1
- #bytes converts an array of integers into their shortest possible
- #bytewise representation.
- try:
- self.socket.sendall(bytes([count]))
- except:
- print("Failed to send... closing down connection")
- self.socket.close()
- self.socketConnected = False
- def dataSetChanged(self, data=None):
- self.data = data
- self.doPlot()
- def doPlot(self):
- if not self.data:
- return
- #PlotWidget's "plot" function expects the fft_mode to have two entries
- #which we don't need here. So we need to shift our index by +2 in order
- #to accomodate for the two missing options in the bucket_select ComboBox
- fft_mode = self.bucketSelect.currentIndex() + 2
- adc = self.adcSelect.currentIndex()
- self.fftData = self.data.fft(adc=self.adcSelect.currentIndex(),
- frm=self.fromBox.value(),
- to=self.toBox.value(),
- drop_first_bin=True,
- nobunching=False)
- self.plot.plot(
- self.fftData,
- autorange=False,
- xvalueborders=[self.data.fftFreqDist(), self.data.fftMaxFreq()],
- fft_mode=fft_mode,
- log=False)
- self.plot.plotItem.setLabel('left', 'Spectral Intensity')
- #I am cheating a little bit and getting the readily processed data
- #from the plotItems, so I don't have to process, convert, format, etc.
- #the fftData again. We already did that in the SubPlotWidget.plot
- #function, so no need to do it again. Just steal the data from the
- #plotItems!
- self.fftYValues = self.plot.plotItemPlot[0].yData
- self.fftXValues = self.plot.plotItemPlot[0].xData
- region = self.region.getRegion()
-
- #Clip to valid data ranges
- rLeft = ceil(region[0]) if region[0] >=0 else 0
- rRight = ceil(region[1]) if region[1] < len(self.fftYValues) else len(self.fftYValues)
- #Make sure the region is within the boundaries of our data array
- if rLeft >= len(self.fftYValues) or rRight < 0:
- self.freqText.setText("Region boundaries out of data range")
- self.line.hide()
- self.isFreqValid = False
- self.freqText.setText("NaN")
- return
- #If the region is not really a region, ignore it
- if rLeft == rRight:
- self.freqText.setText("Region too small")
- self.line.hide()
- self.isFreqValid = False
- self.freqText.setText("NaN")
- return
-
- chunk = self.fftYValues[rLeft:rRight]
- maxVal = np.max(chunk)
- maxIndexInChunk = np.where(chunk == maxVal)
- self.line.setValue(maxVal)
- self.line.show()
-
- #np.where returns a tuple of indices (because it supports
- #multidimensional arrays). But since we know that our array is only
- #1-Dimensional, we can simply pick only the first dimension
- maxIndexInChunk = maxIndexInChunk[0]
- indexInData = rLeft + maxIndexInChunk
- #We are basically just repeating what the plot item also did to
- #determine the X-Axis labeling, and use it calculate the X-Value
- #at the index we have identified
- xAxisScale = (self.data.fftMaxFreq() - self.data.fftFreqDist()) / float(self.fftYValues.shape[0])
- self.freqText.setText(str(self.fftXValues[indexInData][0]*xAxisScale))
- self.isFreqValid = True
- self.sendFreqEth(self.fftXValues[indexInData][0]*xAxisScale)
- def closeEvent(self, event):
- global __widget_id__
- __widget_id__ = None
- del self.par.widgets[self.id]
- self.board_config.unobserve(self, 'lastDataSet')
- def addFrequencyExtractWidget():
- global __widget_id__
- if __widget_id__:
- global_objects.get_global('area').widgets[__widget_id__].setFocus()
- else:
- nid = kcgw.idg.genid()
- __widget_id__ = nid
- w = FrequencyExtractWidget(nid, global_objects.get_global('area'))
- global_objects.get_global('area').newWidget(w, "Frequency Extract", nid, widget_type=4)
- kcgw.register_widget(QtGui.QIcon(config.icon_path("sproject.svg")), "Frequency Extract", addFrequencyExtractWidget, "Ctrl+e")
|