def createDatasetForDisplay(self, display): plotData = PlotDataItem(name=display['label']) if 'color' in display: plotData.setPen(mkPen({'color': display['color']})) return { 'plotData': plotData, 'points': numpy.zeros((constants.NUMPY_ARRAY_SIZE, 2)), }
def __init__(self, name): CtrlNode.__init__(self, name, terminals={ 'x': {'io': 'in'}, 'y': {'io': 'in'}, 'plot': {'io': 'out'} }) self.item = PlotDataItem()
def __init__(self, *args, **kwargs): super(MapViewWidget, self).__init__(*args, **kwargs) # self.scene.sigMouseMoved.connect(self.showSpectra) self.scene.sigMouseClicked.connect(self.showSpectra) self.view.invertY(True) # add arrow self.cross = PlotDataItem([0], [0], symbolBrush=(200, 0, 0), symbolPen=(200, 0, 0), symbol='+', symbolSize=16) self.view.addItem(self.cross) self.cross.hide() #add txt self.txt = TextItem('', anchor=(0, 0)) self.addItem(self.txt)
class PlotCurve(CtrlNode): """Generates a plot curve from x/y data""" nodeName = "PlotCurve" uiTemplate = [("color", "color")] def __init__(self, name): CtrlNode.__init__(self, name, terminals={"x": {"io": "in"}, "y": {"io": "in"}, "plot": {"io": "out"}}) self.item = PlotDataItem() def process(self, x, y, display=True): # print "scatterplot process" if not display: return {"plot": None} self.item.setData(x, y, pen=self.ctrls["color"].color()) return {"plot": self.item}
def make_plt(self): # Reset the plot (i.e., remove all plot elements). self.rset_plt() # Establish the ranges of its time and magnetic field values. # If the core contains no data or only a single datum, # improvise (for the purpose of later establishing axis limits). if (self.core.n_mfi >= 1): # Establish the domain of the plot. t_min = min(amin(self.core.mfi_s), 0.) t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur']) # Establish the range of the plot. As part of this, # ensure that the range satisfies a minimum size and has # sufficient padding. ang_max = max(self.core.mfi_b_lon) ang_min = min(self.core.mfi_b_lon) ang_max = 5. + ang_max ang_min = -5. + ang_min d_t_0 = t_max - t_min d_t = max(1.5 + d_t_0, 3.) t_max = t_min + d_t else: t_min = 0.001 t_max = 3.500 ang_min = -360 ang_max = 360 # Set the range of the axis of each plot. self.plt.setXRange(t_min, t_max, padding=0.0) self.plt.setYRange(ang_min, ang_max, padding=0.0) # If the core contains no Wind/MFI magnetic field data, return. if (self.core.n_mfi <= 0): return # Generate and display each curve for the plot. self.crv_lon = PlotDataItem(self.core.mfi_s, self.core.mfi_b_lon, pen=self.pen_crv_lon) self.plt.addItem(self.crv_lon)
def line(self, x: Optional[np.ndarray], y: np.ndarray, label: Optional[str] = None, line_style: LineStyle = LineStyle.Solid, **kwargs) -> None: x = Axes._create_x(y) if x is None else x kwargs = Axes._add_label_to_kwargs(label, kwargs) self._raw.addItem(PlotDataItem(x=x, y=y, **kwargs))
def __init__(self, *args, **kwargs): PlotDataItem.__init__(self, *args, **kwargs) TaurusBaseComponent.__init__(self, 'TaurusBaseComponent') self._UImodifiable = False self._maxBufferSize = 65536 # (=2**16, i.e., 64K events)) self._xBuffer = None self._yBuffer = None self._curveColors = LoopList(CURVE_COLORS) self._args = args self._kwargs = kwargs self._curves = [] self._timer = Qt.QTimer() self._timer.timeout.connect(self._forceRead) self._legend = None # register config properties self.setModelInConfig(True) self.registerConfigProperty(self._getCurvesOpts, self._setCurvesOpts, 'opts')
def __init__(self, *args, **kwargs): super(MapViewWidget, self).__init__(*args, **kwargs) # self.scene.sigMouseMoved.connect(self.showSpectra) self.scene.sigMouseClicked.connect(self.showSpectra) self.view.invertY(True) # add arrow # self.arrow = ArrowItem(angle=60, headLen=15, tipAngle=45, baseAngle=30, brush = (200, 80, 20)) # self.arrow.setPos(0, 0) self.cross = PlotDataItem([0], [0], symbolBrush=(200, 0, 0), symbolPen=(200, 0, 0), symbol='+', symbolSize=16) self.view.addItem(self.cross) self.cross.hide() #add txt self.txt = TextItem('', anchor=(0, 0)) self.addItem(self.txt)
def _initCurves(self, ntrends): """ Initializes new curves """ # self._removeFromLegend(self._legend) self._curves = [] self._curveColors.setCurrentIndex(-1) a = self._args kw = self._kwargs.copy() base_name = (self.base_name() or taurus.Attribute(self.getModel()).getSimpleName()) for i in range(ntrends): subname = "%s[%i]" % (base_name, i) kw['name'] = subname curve = PlotDataItem(*a, **kw) if 'pen' not in kw: curve.setPen(next(self._curveColors).color()) self._curves.append(curve) self._updateViewBox()
class PlotCurve(CtrlNode): """Generates a plot curve from x/y data""" nodeName = 'PlotCurve' uiTemplate = [ ('color', 'color'), ] def __init__(self, name): CtrlNode.__init__(self, name, terminals={ 'x': {'io': 'in'}, 'y': {'io': 'in'}, 'plot': {'io': 'out'} }) self.item = PlotDataItem() def process(self, x, y, display=True): #print "scatterplot process" if not display: return {'plot': None} self.item.setData(x, y, pen=self.ctrls['color'].color()) return {'plot': self.item}
def set_experiment_view(self): self.ui.graphicsView.clear() plot = PlotDataItem(pen="k") duration = (self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value() xs = np.linspace(0, duration, 2) ys = [1, 1] plot.setData(xs, ys) self.ui.graphicsView.addItem(plot) for ii in range(len(self.Stims.df)): start = self.Stims.df.time_on.iloc[ii] stop = self.Stims.df.time_off.iloc[ii] if self.Stims.df.message_on.iloc[ii].startswith("w"): box = LinearRegionItem(values=(start, stop), brush=(255, 255, 250, 230), movable=False) self.ui.graphicsView.addItem(box) elif self.Stims.df.message_on.iloc[ii].startswith("n"): on = self.Stims.df.message_on.iloc[ii][1:] r = int(on[:3]) g = int(on[3:6]) b = int(on[6:]) box = LinearRegionItem(values=(start, stop), brush=(r, g, b, 50), movable=False) self.ui.graphicsView.addItem(box) elif self.Stims.df.message_on.iloc[ii].startswith("v"): box = LinearRegionItem(values=(start, stop), brush="k", movable=False) self.ui.graphicsView.addItem(box) self.ui.comboBoxSelectStimId.clear() for stim_id in set(self.Stims.df.id): self.ui.comboBoxSelectStimId.addItem(stim_id)
def visualize(self, larlite_io, larcv_io, rawdigit_io): event_imgs = larcv_io.get_data(larcv.kProductImage2D, self.producer) event_hits = larcv_io.get_data(larcv.kProductImage2D, self.hit_producer) lcv_imgs = event_imgs.Image2DArray() lcv_hits = event_hits.Image2DArray() pixel_vecs = [] # output container for iimg in xrange(0, lcv_imgs.size()): lcv_img = lcv_imgs.at(iimg) lcv_hit = lcv_hits.at(iimg) meta = lcv_img.meta() angimg = larcv.as_ndarray(lcv_img) hitpx = larcv.as_ndarray(lcv_hit) hits = np.argwhere(hitpx > 0.1) print "number of hits: ", len(hits) vec_data_x = np.zeros(2 * len(hits)) # we make pair of points for vec vec_data_y = np.zeros(2 * len(hits)) # we make pair of points for vec for i, hit in enumerate(hits): # set origin x = meta.pos_x(hit[0]) y = meta.pos_y(hit[1]) vec_data_x[2 * i] = x vec_data_y[2 * i] = y ang = angimg[hit[0], hit[1]] dx = np.cos(ang) * meta.pixel_width() dy = np.sin(ang) * meta.pixel_height() vec_data_x[2 * i + 1] = x + dx vec_data_y[2 * i + 1] = y - dy # (-) because origin of y is top corner plot = PlotDataItem(x=vec_data_x, y=vec_data_y, pen=(255, 255, 255, 100), connect='pairs') pixel_vecs.append(plot) return pixel_vecs
def plot(self, x: Optional[np.ndarray], y: np.ndarray, label: Optional[str] = None, marker_style: MarkerStyle = MarkerStyle.Dot, **kwargs) -> None: x = Axes._create_x(y) if x is None else x kwargs = Axes._add_label_to_kwargs(label, kwargs) # self._raw.plot(x=x, y=y, pen=None, **marker_style_to_dict(marker_style), **kwargs) self._raw.addItem( PlotDataItem(x=x, y=y, pen=None, **marker_style_to_dict(marker_style), **kwargs))
def __init__(self, *args, **kwargs): """ Accepts same args and kwargs as PlotDataItem, plus: :param xModel: (str) Taurus model name for abscissas values. Default=None :param yModel: (str) Taurus model name for ordinate values. Default=None """ xModel = kwargs.pop('xModel', None) yModel = kwargs.pop('yModel', None) PlotDataItem.__init__(self, *args, **kwargs) TaurusBaseComponent.__init__(self, 'TaurusBaseComponent') self._x = None self._y = None self.xModel = None if xModel is not None: self.setXModel(xModel) if yModel is not None: self.setModel(yModel) self.registerConfigProperty(self.getOpts, self.setOpts, 'opts') self.setModelInConfig(True) self.registerConfigProperty(self.getXModelName, self.setXModel, 'XModel')
def __init__(self, name): Node.__init__(self, name, terminals={ 'dataIn': { 'io': 'in' }, 'dataOut': { 'io': 'out' }, 'plotItems': { 'io': 'out' } }) color = (220, 220, 25, 255) self.plotDataItem = PlotDataItem(stepMode=True, fillLevel=0, pen={ 'color': color, 'width': 2 }) self.plotRegion = LinearRegionItem([0, 1], movable=True) self.plotRegion.sigRegionChangeFinished.connect(self.regionChanged) self.sigUpdatePlot.connect(self.updatePlot)
def stylingPlot(self): colorDefault = self.palette().color(QtGui.QPalette.Window) plot = self._ui.pnlPlot plot.setBackground(colorDefault) plot.setTitle( "Daily number of Cases and Deaths in Spain (14-day mean)", color=(57, 57, 58), size="18pt") styles = {'color': (57, 57, 58), 'font-size': '12px'} plot.setLabel('left', 'Infections', **styles) plot.setLabel('right', 'Deaths', **styles) plot.showGrid(x=False, y=True) plot2 = PlotDataItem([0, 1, 2, 8], [48, 57, 14, 3], antialias=True) plot.addItem(plot2)
def histogram(self, data: np.ndarray, label: Optional[str] = None, bins: int = 10, data_range: Optional[Tuple[Optional[float], Optional[float]]] = None, line_style: LineStyle = LineStyle.Solid, orientation: Orientation = Orientation.Vertical, **kwargs) -> None: hist, bin_list = np.histogram(data, bins=bins, range=Axes._data_range(data_range, data)) kwargs = Axes._add_label_to_kwargs(label, kwargs) if orientation == Orientation.Vertical: self._raw.addItem( PlotDataItem(x=bin_list, y=hist, stepMode=True, **kwargs)) else: raise NotImplementedError
class ComponentPlotWidget(SpectraPlotWidget): def __init__(self, *args, **kwargs): super(ComponentPlotWidget, self).__init__(linePos=800, txtPosRatio=0.35, *args, **kwargs) self.cross = PlotDataItem([800], [0], symbolBrush=(255, 255, 255), symbolPen=(255, 255, 255), symbol='+', symbolSize=25) self._x, self._y = None, None self.ymax, self.zmax = 0, 100 def getEnergy(self): if self._y is not None: x_val = self.line.value() idx = val2ind(x_val, self._x) x_val = self._x[idx] y_val = self._y[idx] txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt.setHtml(txt_html) self.cross.setData([x_val], [y_val]) def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position plot_item = self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) self.addItem(self.cross) x_val = self.line.value() idx = val2ind(x_val, x) x_val = x[idx] y_val = y[idx] txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt.setHtml(txt_html) self.txt.setZValue(self.zmax - 1) self.cross.setData([x_val], [y_val]) self.cross.setZValue(self.zmax) ymax = max(y) if ymax > self.ymax: self.ymax = ymax self._x, self._y = x, y r = self.txtPosRatio self.txt.setPos(r * x[-1] + (1 - r) * x[0], self.ymax) self.addItem(self.txt) return plot_item
def add_plot_item(self, i, x, y, colour=Qt.red): """Add a plot item representing two already added data series. :param i: Id of the plot item. Should be ascending natural numbers from 0 up. :type i: int :param x: Id of the data series holding the x values. :type x: int :param y: Id of the data series holding the y values. :type y: int :param colour: Colour of the plot item. The default is red. :type colour: str|QRgb|QColor|Qt.GlobalColor """ self.items[i] = {"x": x, "y": y} self.data[x]["items"].append(i) self.data[y]["items"].append(i) self.items[i]["plot"] = PlotDataItem( \ self.data[x]["data"], \ self.data[y]["data"], \ pen=QColor(colour)) self.widget.addItem(self.items[i]["plot"])
def make_plt(self): # Reset the plot (i.e., remove all plot elements). self.rset_plt() # Establish the ranges of its time and magnetic field values. # If the core contains no data or only a single datum, # improvise (for the purpose of later establishing axis limits). if (self.core.n_mfi >= 1): # Establish the domain of the plot. t_min = min(amin(self.core.mfi_s), 0.) t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur']) # Establish the range of the plot. As part of this, # ensure that the range satisfies a minimum size and has # sufficient padding. b_max = amax(self.core.mfi_b) b_min = -b_max d_t_0 = t_max - t_min d_b_0 = b_max - b_min d_t = max(1.5 + d_t_0, 3.) d_b = max(1.2 * d_b_0, 5.) t_max = t_min + d_t b_min = b_min - (d_b - d_b_0) / 2. b_max = b_max + (d_b - d_b_0) / 2. else: t_min = 0.001 t_max = 3.500 b_min = -2.5 b_max = 2.5 # Set the range of the axis of each plot. self.plt.setXRange(t_min, t_max, padding=0.0) self.plt.setYRange(b_min, b_max, padding=0.0) # Set the PESA-L pen with a width corresponding to one rotation # Note: For some reason, the lines are not wide enough unless 5 # is added to the scaled width of the rotation time rot = 3.05 * self.axs_x.width() / (t_max - t_min) + 5 self.pen_pl = mkPen(color=(245, 245, 245), width=rot) # If the core contains no Wind/MFI magnetic field data, return. if (self.core.n_mfi <= 0): return # Generate and display each curve for the plot. self.crv_m = PlotDataItem(self.core.mfi_s, self.core.mfi_b, pen=self.pen_crv_m) self.crv_n = PlotDataItem(self.core.mfi_s, [-b for b in self.core.mfi_b], pen=self.pen_crv_n) self.crv_x = PlotDataItem(self.core.mfi_s, self.core.mfi_b_x, pen=self.pen_crv_x) self.crv_y = PlotDataItem(self.core.mfi_s, self.core.mfi_b_y, pen=self.pen_crv_y) self.crv_z = PlotDataItem(self.core.mfi_s, self.core.mfi_b_z, pen=self.pen_crv_z) # If PESA-L spectra were loaded, add the vertical indicators # showing their time relative to the start of the FC spectrum for n in range(len(self.core.pl_spec_arr)): time = self.core.pl_spec_arr[n]['time'][0] t_0 = self.core.fc_spec['time'] delta_t = (time - t_0).total_seconds() self.pl += [ InfiniteLine(delta_t + self.core.fc_spec['rot'] / 2., pen=self.pen_pl) ] for i in range(len(self.pl)): self.plt.addItem(self.pl[i]) self.plt.addItem(self.crv_m) self.plt.addItem(self.crv_n) self.plt.addItem(self.crv_x) self.plt.addItem(self.crv_y) self.plt.addItem(self.crv_z)
class MapViewWidget(DynImageView): sigShowSpectra = Signal(int) def __init__(self, *args, **kwargs): super(MapViewWidget, self).__init__(*args, **kwargs) # self.scene.sigMouseMoved.connect(self.showSpectra) self.scene.sigMouseClicked.connect(self.showSpectra) self.view.invertY(True) # add arrow # self.arrow = ArrowItem(angle=60, headLen=15, tipAngle=45, baseAngle=30, brush = (200, 80, 20)) # self.arrow.setPos(0, 0) self.cross = PlotDataItem([0], [0], symbolBrush=(200, 0, 0), symbolPen=(200, 0, 0), symbol='+', symbolSize=16) self.view.addItem(self.cross) self.cross.hide() #add txt self.txt = TextItem('', anchor=(0, 0)) self.addItem(self.txt) def setEnergy(self, lineobject): E = lineobject.value() # map E to index i = val2ind(E, self.wavenumbers) # print('E:', E, 'wav:', self.wavenumbers[i]) self.setCurrentIndex(i) def showSpectra(self, event): pos = event.pos() if self.view.sceneBoundingRect().contains( pos ): # Note, when axes are added, you must get the view with self.view.getViewBox() mousePoint = self.view.mapSceneToView(pos) x, y = int(mousePoint.x()), int(mousePoint.y()) y = self.row - y - 1 try: ind = self.rc2ind[(y, x)] self.sigShowSpectra.emit(ind) # print(x, y, ind, x + y * self.n_col) #update arrow self.cross.setData([x + 0.5], [self.row - y - 0.5]) self.cross.show() # update text self.txt.setHtml( f'<div style="text-align: center"><span style="color: #FFF; font-size: 8pt">X: {x}</div>\ <div style="text-align: center"><span style="color: #FFF; font-size: 8pt">Y: {y}</div>\ <div style="text-align: center"><span style="color: #FFF; font-size: 8pt">Point: #{ind}</div>' ) except Exception: self.cross.hide() def setHeader(self, header: NonDBHeader, field: str, *args, **kwargs): self.header = header self.field = field imageEvent = next(header.events(fields=['image'])) self.rc2ind = imageEvent['rc_index'] self.wavenumbers = imageEvent['wavenumbers'] # make lazy array from document data = None try: data = header.meta_array(field) self.row = data.shape[1] self.col = data.shape[2] self.txt.setPos(self.col, 0) except IndexError: msg.logMessage( 'Header object contained no frames with field ' '{field}' '.', msg.ERROR) if data is not None: # kwargs['transform'] = QTransform(1, 0, 0, -1, 0, data.shape[-2]) self.setImage(img=data, *args, **kwargs) self._data = data def updateImage(self, autoHistogramRange=True): super(MapViewWidget, self).updateImage(autoHistogramRange) self.ui.roiPlot.setVisible(False) def setImage(self, img, **kwargs): super(MapViewWidget, self).setImage(img, **kwargs) self.ui.roiPlot.setVisible(False) def makeMask(self, thresholds): peak1550 = val2ind(1550, self.wavenumbers) thr1550 = thresholds[0] mask = self._data[peak1550] > thr1550 mask = mask.astype(np.int) return mask
return Gematron_proc_obj.get_image(file_path).T win.add_image_plot_with_axes('Gematron', 'Gematron', gematron_image, [(0, 0), (2048, 2048)], [(0, 0), (2048, 2048)]) for f_rect in Gematron_proc_obj.filter_rects: # self.filter_rects.append([(minc, minr), maxc - minc, maxr - minr]) # arguments for overlaying rectangle as below... # rect = mpatches.Rectangle(f_rect[0], f_rect[1], f_rect[2], # fill=False, edgecolor='red', linewidth=1, ls='--') minr, minc, maxr, maxc = f_rect xValues = [minc, minc, maxc, maxc, minc] yValues = [minr, maxr, maxr, minr, minr] win.docks['Gematron'].widgets[0].view.addItem( PlotDataItem(xValues, yValues, pen=dict(color='r', dash=[4, 4]))) win.add_scalar_history_plot('Gematron E_c', 'Gematron', HistoryShots, get_E_crit) win.add_scalar_history_plot('Gematron photons', 'Gematron', HistoryShots, get_beam_N) win.add_scalar_history_plot('Gematron mean counts', 'Gematron', HistoryShots, get_mean_beam_counts) server.diag_list.addItem('Gematron') ## dx420 plots def basic_image(file_path):
def __init__(self, name, plot_item_data_params, *args, **kwargs): """ Constructor. Args: name (str): name of plot. Also show in the title section of the plot; plot_item_data_params (list): dictionary of ``DataBuffer`` and respective parameters; *args: positional arguments to be passed to ``PlotItem`` class; **kwargs: dictionary to be passed to ``PlotItem`` class. """ mkQApp() self.data_buffers = list() self._plot_drawing_params = list() self._curves_names = [] self._refresh_activated = True self.name = name if len(plot_item_data_params) == 1 and ( "pen" not in plot_item_data_params[0]): plot_item_data_params[0]["pen"] = mkPen(color='r') if len(plot_item_data_params) > 1: for single_params in plot_item_data_params: colors = self.get_n_colors(len(plot_item_data_params)) if "pen" not in single_params: color = colors[plot_item_data_params.index(single_params)] color = list(color) color.append(255) single_params["pen"] = mkPen(color=mkColor(tuple(color))) if "name" not in single_params: single_params["name"] = single_params["data_buffer"].name for single_params in plot_item_data_params: self.data_buffers.append(single_params["data_buffer"]) self._curves_names.append(single_params["data_buffer"].name) single_params.pop("data_buffer", None) self._plot_drawing_params.append(single_params) kwargs['title'] = self.name super().__init__(*args, **kwargs) if not isinstance(self.data_buffers, list): self.data_buffers = [self.data_buffers] self.plot_data_items_list = list() if self._plot_drawing_params is not None: for data_buffer, plot_drawing_param in zip( self.data_buffers, self._plot_drawing_params): self.plot_data_items_list.append( PlotDataItem(data_buffer.get(), **plot_drawing_param)) else: for data_buffer, plot_drawing_param in zip( self.data_buffers, self._plot_drawing_params): self.plot_data_items_list.append( PlotDataItem(data_buffer.get(), **plot_drawing_param)) if self.len_curves > 1: self.addLegend()
def make_crv( self ) : # If no "list" of "p" index-values has been provided by the # user, assume that the curves in all plots should be # (re-)rendered. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # Return the "nln_psd_gss_ion axes to their original order. if( self.core.nln_psd_gss_ion is not None ) : if( self.core.nln_psd_gss_ion != [ ] ) : nln_psd_gss_ion = [ [ [ [ [ self.core.nln_psd_gss_ion[n][t][f][b][p] for b in range( self.core.pl_spec_arr[n]['n_bin'] ) ] for f in range( self.core.pl_spec_arr[n]['n_phi'] ) ] for t in range( self.core.pl_spec_arr[n]['n_the'] ) ] for n in range( len( self.core.pl_spec_arr ) ) ] for p in range( self.core.nln_gss_n_pop ) ] # Return the "nln_res_psd_ion axes to their original order. if( self.core.nln_res_psd_ion is not None ) : if( self.core.nln_res_psd_ion != [ ] ) : nln_res_psd_ion = [ [ [ [ [ self.core.nln_res_psd_ion[n][t][f][b][p] for b in range( self.core.pl_spec_arr[n]['n_bin'] ) ] for f in range( self.core.pl_spec_arr[n]['n_phi'] ) ] for t in range( self.core.pl_spec_arr[n]['n_the'] ) ] for n in range( len( self.core.pl_spec_arr ) ) ] for p in range( self.core.nln_gss_n_pop ) ] # For each plot in the grid, generate and display a fit curve # based on the results of the analysis. vel_cen = self.core.pl_spec_arr[self.n]['vel_cen'] for t in range( self.core.pl_spec_arr[self.n]['n_the'] ) : for p in range( self.core.pl_spec_arr[self.n]['n_phi'] ) : # If this plot does not exist, move onto the next grid # element. if ( self.plt[t,p] is None ) : continue # If any curves already exist for this plot, remove and # delete them. if ( self.crv[t,p] is not None ) : self.plt[t,p].removeItem( self.crv[t,p] ) self.crv[t,p] = None for n in range( self.n_ion ) : if ( self.crv_ion[t,p,n] is not None ) : self.plt[t,p].removeItem( self.crv_ion[t,p,n] ) self.crv_ion[t,p,n] = None # Create and add the curve of the indiviadual # contributions to the modeled psd to the plot. for n in range( ( 1 if self.core.dsp == 'mom' else self.core.nln_gss_n_pop ) ) : # Extract the points for this fit curve. x = array( vel_cen ) if( self.core.dsp == 'mom' ) : y = array( self.core.pl_spec_arr[self.n]['psd_mom'][t][p] ) elif( self.core.dsp == 'gsl' ) : y = array( nln_psd_gss_ion[n][self.n][t][p] ) elif( self.core.dsp == 'nln' ) : y = array( nln_res_psd_ion[n][self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv_ion[t,p,n] = PlotDataItem( ax, ay, pen=( self.pen_crv_b if self.core.dsp=='mom' else self.pen_crv_g ) ) self.plt[t,p].addItem( self.crv_ion[t,p,n] ) # If applicable, create and add the curve of the # total contributions to the modeled psd to the # plot if( self.core.dsp == 'gsl' ) : x = array( vel_cen ) y = array( self.core.nln_psd_gss_tot[self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv[t,p] = PlotDataItem( ax, ay, pen=( self.pen_crv_b ) ) self.plt[t,p].addItem( self.crv[t,p] ) # If applicable, create and add the curve of the # total contributions to the non-linear psd to # the plot if( ( self.core.dsp == 'nln' ) and ( self.core.nln_res_psd_tot is not None ) ) : x = array( vel_cen ) y = array( self.core.nln_res_psd_tot[self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv[t,p] = PlotDataItem( ax, ay, pen=( self.pen_crv_b ) ) self.plt[t,p].addItem( self.crv[t,p] )
def show_solution(self, task): """:param task: объект модели TaskModel""" self.plotter.plotItem.clear() self.plotter.plotItem.legend.clear() self.coefs = task.inequalities_coefs.split(',') self.consts = task.inequalities_consts.split(',') try: solver = Solver(task) except AttributeError: QMessageBox.warning( self, 'Ошибка!', 'Похоже, у задачи заполнены не все данные. ' 'Проверьте правильность входных данных.') return self.mark = '≥' if solver.lim == TaskModel.LIM_ZERO else '≤' for i, constraint in enumerate(solver.get_constraints()[:, :, ::-1]): pen = self.plotter.pen() if constraint[0][1] == np.inf: self.plotter.addLine(constraint[1][0], angle=90, pen=pen) self.plotter.plotItem.legend.addItem( PlotDataItem(pen=pen), name=self.render_constraint(i)) elif constraint[1][0] == np.inf: self.plotter.addLine(constraint[0][1], angle=0, pen=pen) self.plotter.plotItem.legend.addItem( PlotDataItem(pen=pen), name=self.render_constraint(i)) else: self.plotter.plot(x=constraint[:, ::2].ravel(), y=constraint[:, 1::2].ravel(), name=self.render_constraint(i), pen=self.plotter.pen()) bounds = solver.get_bounds(5, 0) self.plotter.plotItem.vb.setLimits(**bounds) try: point, opt_value = solver.solve() except NoSolutionError: QMessageBox.warning( self, 'Ошибка!', 'Похоже, у задачи нет решения. Проверьте правильность входных данных.' ) return except SolverException as e: QMessageBox.warning( self, 'Ошибка!', f'К сожалению, задачу решить не удалось.\nПричина: {e}') return except Exception as e: QMessageBox.warning( self, 'Непредвиденная ошибка!', f'В ходе решения произошла непредвиденная ошибка {e}') return if solver.lim == TaskModel.LIM_INF: p_points = solver.get_possible_points() if len(p_points) > 2: self.plotter.plot(x=tuple(p_points.keys()), y=tuple(p_points.values()), brush=QColor(0, 0, 255, 90), pen=None, fillLevel=bounds['xMin'] if solver.lim == TaskModel.LIM_INF else bounds['xMax']) self.plotter.plot( x=[0, opt_value / solver.coefs[0] * solver.lim], y=[opt_value / solver.coefs[1] * solver.lim, 0], pen=self.plotter.pen('r'), name= '<p style="font-size: 12pt; font-family:Georgia, \'Times New Roman\', ' 'Times, serif">Целевая функция, проходящая через точку ' f'А({point[0]:.2g}, {point[1]:.2g})</p>') self.plotter.plot( x=[point[0]], y=[point[1]], symbol='+', symbolSize=20, symbolBrush='b', symbolPen=None, pen=None, name= '<p style="font-size: 12pt; font-family:Georgia, \'Times New Roman\', ' f'Times, serif">Оптимальное значение ЦФ ({opt_value:.2g})</p>') super().show()
def make_crv(self, p_lst=None): # If no "list" of "p" index-values has been provided by the # user, assume that the curves in all plots should be # (re-)rendered. if (p_lst is None): p_lst = range(min(self.core.n_azm, self.n_plt)) # If the results of the analysis are missing, abort; otherwise, # extract the current values to be plotted. if (self.core.dsp == 'mom'): cur = self.core.mom_cur cur_ion = None elif (self.core.dsp == 'gsl'): cur = self.core.nln_gss_cur_tot cur_ion = self.core.nln_gss_cur_ion elif (self.core.dsp == 'nln'): cur = self.core.nln_res_cur_tot cur_ion = self.core.nln_res_cur_ion else: cur = None cur_ion = None # For each plot in the grid, generate and display a fit curve # based on the results of the analysis. for p in p_lst: # Determine the location of this plot within the grid # layout. j = self.calc_ind_j(p) i = self.calc_ind_i(p) # If this plot does not exist, move onto the next grid # element. if (self.plt[j, i] is None): continue # If any curves already exist for this plot, remove and # delete them. if (self.crv[j, i] is not None): self.plt[j, i].removeItem(self.crv[j, i]) self.crv[j, i] = None for n in range(self.n_ion): if (self.crv_ion[j, i, n] is not None): self.plt[j, i].removeItem(self.crv_ion[j, i, n]) self.crv_ion[j, i, n] = None # Create and add the curve of the individual # contributions to the modeled current to the plot. if (cur_ion is not None): for n in range(len(cur_ion[self.t, p, 0, :])): # Extract the points for this fit curve. x = self.core.vel_cen y = cur_ion[self.t, p, :, n] # Select only those points for which # the fit current is strictly positive. tk = where(y > 0.)[0] # If fewer than two curve points were # selected, skip plotting this curve. if (len(tk) < 2): continue # Generate the adjusted points for this # curve. if (self.log_x): ax = log10(x[tk]) else: ax = x[tk] if (self.log_y): ay = log10(y[tk]) else: ay = y[tk] # Create, store, and add to the plot # this fit curve. self.crv_ion[j, i, n] = PlotDataItem(ax, ay, pen=self.pen_crv_g) self.plt[j, i].addItem(self.crv_ion[j, i, n]) # Create, store, and add to the plot a curve for the # total fit current. if (cur is not None): # Extract the points of the fit curve. x = self.core.vel_cen y = cur[self.t, p, :] # Select only those points for which the fit # current is strictly positive. tk = where(y > 0.)[0] # If at least two points were selected, proceed # with plotting. if (len(tk) >= 2): # Generate the adjusted points for this # curve. if (self.log_x): ax = log10(x[tk]) else: ax = x[tk] if (self.log_y): ay = log10(y[tk]) else: ay = y[tk] # Create, store, and add to the plot # this fit curve. self.crv[j, i] = PlotDataItem(ax, ay, pen=self.pen_crv_b) self.plt[j, i].addItem(self.crv[j, i])
class makeTimeseriesCurveNode(NodeWithCtrlWidget): """Prepare Timeseries for plotting. Generate curve that can be viewed with node *TimeseriesPlot* and pd.Series with datetime stored in Index """ nodeName = "Make Curve" uiTemplate = [ {'name': 'Y:signal', 'type': 'list', 'value': None, 'default': None, 'values': [None], 'tip': 'Signal Data-Values (Y-axis)'}, {'name': 'X:datetime', 'type': 'list', 'value': None, 'default': None, 'values': [None], 'tip': 'Datetime Values (X-axis)'}, {'name': 'tz correct', 'type': 'float', 'value': 0, 'default': 0, 'suffix': ' hours', 'tip': '<float>\nONLY FOR CURVE!!!\nTimezone correction\nNumber of hours to add/substract from result. Due to missing\ntimezone settings it may be nessesary to use this parameter.\nCheck the results manually with *TimeseriesPlot* Node'}, {'name': 'color', 'type': 'color', 'tip': 'Curve color'}, {'name': 'Display Line', 'type': 'bool', 'value': True, 'tip': 'display line-curve between data points', 'children': [ {'name': 'Style', 'type': 'list', 'tip': 'Style', 'values': {'solid': QtCore.Qt.SolidLine, 'dash': QtCore.Qt.DashLine, 'dash-dot': QtCore.Qt.DashDotLine, 'dot-dot': QtCore.Qt.DotLine, 'dash-dot-dot': QtCore.Qt.DashDotDotLine }}, {'name': 'Linewidth', 'type': 'float', 'value': 1., 'limits': (0., 20.), 'step': 0.1, 'tip': 'Linewidth'}, ]}, {'name': 'Display Data Points', 'type': 'bool', 'value': False, 'tip': 'display data points as scatter', 'children': [ {'name': 'Symbol', 'type': 'list', 'tip': 'Symbol for data points', 'value': 'o', 'values': {'circle': 'o', 'triangle': 't', 'square': 's', 'pentagon': 'p', 'hexagon': 'h', 'star': 'star', 'cross': '+', 'diamond': 'd'}}, {'name': 'Size', 'type': 'int', 'value': 5, 'limits': (0, 1000), 'tip': 'Symbol size'}, ]}, ] def __init__(self, name, parent=None): super(makeTimeseriesCurveNode, self).__init__(name, parent=parent, terminals={'df': {'io': 'in'}, 'pd.Series': {'io': 'out'}, 'Curve': {'io': 'out'}}, color=(150, 150, 250, 150)) self._plotRequired = False self.item = PlotDataItem(clipToView=False) def _createCtrlWidget(self, **kwargs): return makeTimeseriesCurveNodeCtrlWidget(**kwargs) def process(self, df): if df is None: del self.item self.item = None return {'Curve': None, 'pd.Series': None } if self.item is None: self.item = PlotDataItem(clipToView=False) colname = [col for col in df.columns if isNumpyNumeric(df[col].dtype)] self._ctrlWidget.param('Y:signal').setLimits(colname) colname = [col for col in df.columns if isNumpyDatetime(df[col].dtype)] self._ctrlWidget.param('X:datetime').setLimits(colname) with BusyCursor(): kwargs = self.ctrlWidget().prepareInputArguments() #self.item = PlotDataItem(clipToView=False) t = df[kwargs['X:datetime']].values # part 1 timeSeries = pd.DataFrame(data=df[kwargs['Y:signal']].values, index=t, columns=[kwargs['Y:signal']]) # part 2 # convert time b = t.astype(np.dtype('datetime64[s]')) timeStamps = b.astype(np.int64)-kwargs['tz correct']*60*60+time.timezone # now create curve pen = fn.mkPen(color=kwargs['color'], width=kwargs['width'], style=kwargs['style']) self.item.setData(timeStamps, df[kwargs['Y:signal']].values, pen=pen, name=kwargs['Y:signal']) self.item.setSymbol(kwargs['symbol']) if kwargs['symbol'] is not None: self.item.setSymbolPen(kwargs['color']) self.item.setSymbolBrush(kwargs['color']) self.item.setSymbolSize(kwargs['symbolSize']) return {'Curve': self.item, 'pd.Series': timeSeries }
def make_crv( self, d_lst=None ) : # If no "list" of "p" index-values has been provided by the # user, assume that the curves in all plots should be # (re-)rendered. if ( self.core.fc_spec is None ) : return if ( d_lst is None ) : d_lst = range( min( self.core.fc_spec['n_dir'], self.n_plt ) ) # If the results of the analysis are missing, abort; otherwise, # extract the current values to be plotted. if ( self.core.dsp == 'mom' ) : curr = self.core.mom_curr curr_ion = None elif ( self.core.dsp == 'gsl' ) : curr = self.core.nln_gss_curr_tot curr_ion = self.core.nln_gss_curr_ion elif ( self.core.dsp == 'nln' ) : curr = self.core.nln_res_curr_tot curr_ion = self.core.nln_res_curr_ion else : curr = None curr_ion = None # For each plot in the grid, generate and display a fit curve # based on the results of the analysis. vel_cen = self.core.fc_spec['vel_cen'][self.c] for d in d_lst : # Determine the location of this plot within the grid # layout. j = self.calc_ind_j( d ) i = self.calc_ind_i( d ) # If this plot does not exist, move onto the next grid # element. if ( self.plt[j,i] is None ) : continue # If any curves already exist for this plot, remove and # delete them. if ( self.crv[j,i] is not None ) : self.plt[j,i].removeItem( self.crv[j,i] ) self.crv[j,i] = None for n in range( self.n_ion ) : if ( self.crv_ion[j,i,n] is not None ) : self.plt[j,i].removeItem( self.crv_ion[j,i,n] ) self.crv_ion[j,i,n] = None # Create and add the curve of the individual # contributions to the modeled current to the plot. if ( curr_ion is not None ) : for n in range( len( curr_ion[self.c][d][0] ) ) : # Extract the points for this fit curve. x = array( vel_cen ) y = array( [ curr_ion[self.c][d][b][n] for b in range( self.core.fc_spec['n_bin'] ) ] ) # Select only those points for which # the fit current is strictly positive. tk = where( y > 0. )[0] # If fewer than two curve points were # selected, skip plotting this curve. if ( len( tk ) < 2 ) : continue # Generate the adjusted points for this # curve. if ( self.log_x ) : ax = log10( x[tk] ) else : ax = x[tk] if ( self.log_y ) : ay = log10( y[tk] ) else : ay = y[tk] # Create, store, and add to the plot # this fit curve. self.crv_ion[j,i,n] = PlotDataItem( ax, ay, pen=self.pen_crv_g ) self.plt[j,i].addItem( self.crv_ion[j,i,n] ) # Create, store, and add to the plot a curve for the # total fit current. if ( curr is not None ) : # Extract the points of the fit curve. x = [ self.core.fc_spec.arr[self.c][0][b][ 'vel_cen'] for b in range( self.core.fc_spec['n_bin'] ) ] y = curr[self.c][d] x = array( x ) y = array( y ) # Select only those points for which the fit # current is strictly positive. valid = [ yy > 0. for yy in y ] n_a = sum( valid ) ax = [ xx for xx, vv in zip( x, valid ) if vv ] ay = [ yy for yy, vv in zip( y, valid ) if vv ] # If at least two points were selected, proceed # with plotting. if ( n_a >= 2 ) : # If needed, convert to a logarithmic # scale. if ( self.log_x ) : ax = [ log10( xx ) for xx in ax ] if ( self.log_y ) : ay = [ log10( yy ) for yy in ay ] # Create, store, and add to the plot # this fit curve. self.crv[j,i] = PlotDataItem( ax, ay, pen=self.pen_crv_b ) self.plt[j,i].addItem( self.crv[j,i] )
def __init__(self, name): CtrlNode.__init__(self, name, terminals={"x": {"io": "in"}, "y": {"io": "in"}, "plot": {"io": "out"}}) self.item = PlotDataItem()
class ScanPlot(PlotItem): # scan is the scan json object def __init__(self,parent,scan): # name of independent variable input = scan[INPUT] x_label = input.get(NAME,'input') x_units = input.get(UNITS,'arb') # name of dependent variable output = scan[OUTPUT] if type(output) is dict: y_label = output.get(NAME,'output') y_units = output.get(UNITS,'arb') else: y_label = 'output' y_units = 'arb' # scan title title = scan.get( NAME, '%s vs. %s' % (y_label,x_label) ) labels = { 'bottom':'%s (%s)' % (x_label,x_units), 'left':'%s (%s)' % (y_label,y_units) } # initialize pyqtgraph plot item with title and axis labels PlotItem.__init__( self, title = title, labels = labels ) # are we setting input to optimal value of scan result? self.optimizing = scan.get(OPTIMIZE,False) # if we have multiple outputs and are optimizing, which output to optimize? self.checking_optimize = scan.get(CHECK_OPTIMIZE,False) self.click_deferred = None self.optimize_axis = scan.get(OPTIMIZE_AXIS,0) # are we saving scan data to datavault? self.saving = scan.get(SAVE,False) # are we returning to input's original position after scan? self.returning = scan.get(RETURN,False) self.scan = scan self.__parent = parent def mouseClickEvent(self,event): if self.click_deferred is not None: self.click_deferred.callback(self.getViewBox().mapSceneToView(event.scenePos()).x()) event.accept() self.click_deferred = None else: PlotItem.mouseClickEvent(self,event) # performs set up for scan def start(self): return self.set_scan_items() @inlineCallbacks def set_scan_items(self): scan = self.scan outputs = scan[OUTPUT] if type(outputs) is dict: outputs = [outputs] if self.is_saving(): # get labrad connection cxn = yield connectAsync() # get handle to data vault data_vault = cxn.data_vault # list of folders (trunk to leaf) for dataset directory save_dir = scan.get(SAVE_DIR,[]) # go to scans dir in dv yield data_vault.cd(data_vault_dir+save_dir,True) independent_variables = [ '%s [%s]' % ( scan[INPUT].get(NAME,'input'), scan[INPUT].get(UNITS,'arb') ) ] dependent_variables = [ '%s [%s]' % ( output.get(NAME,'output'), output.get(UNITS,'arb') ) for output in outputs ] save_name = scan.get(SAVE_NAME,None) default_name = text=scan.get(NAME,'') if save_name is None: save_name, result = QtGui.QInputDialog.getText( self.__parent, 'enter dataset name', 'enter title for data vault dataset', text = default_name ) if not result: save_name = default_name # create new dataset yield data_vault.new( str(save_name), independent_variables, dependent_variables ) # make note of dataset creation yield data_vault.add_parameter( 'time', get_datetime() ) self.data_vault = data_vault # instantiate scan input object self.input = INPUTS[ scan[INPUT][CLASS] ]( **mangle(scan[INPUT].get(ARGS,{})) ) # note initial position if we are planning to return to it after scan if self.is_returning(): self._return_input = yield self.input._get_input() # instantiate scan output object self.outputs = [ OUTPUTS[ output[CLASS] ]( **mangle(output.get(ARGS,{})) ) for output in outputs ] # intialize x and y values self.x_data = [] self.y_datas = [] # clear any stuff that happens to be in plot (TODO: do we ever scan the same object twice?) for item in self.allChildItems(): self.removeItem(item) # if optimizing or have multiple sources, \ # add legend to distinguish different sources if self.is_optimizing() or len(outputs) > 1: self.addLegend() if self.is_optimizing(): # initialize fit curve self.fit_curve = PlotDataItem( name='fit (%s)' % outputs[ self.optimize_axis ].get( NAME, 'output %d' % (self.optimize_axis+1) ), pen={'color':'BBB','width':2} ) # initialize data curves self.curves = [ self.plot( name=output.get(NAME,'output %d' % (index + 1)), pen=None, symbolSize=5, symbolPen=None, symbolBrush=('F55','5F5','55F','FF5','5FF','F5F')[index % 6] ) for index, output in enumerate(outputs) ] def show_fit(self): self.addItem(self.fit_curve) # put input back to initial position def return_input(self): return self.input.set_input(self._return_input) # called to increment scan by one step @inlineCallbacks def step(self): # ask input for next x value x = yield self.input.get_input() # check if scan input is done and err if so if x is None: returnValue(False) y = [] output_deferreds = [ output.get_output() for output in self.outputs ] for deferred in output_deferreds: y_value = yield deferred y.append(y_value) # add new values to data arrays self.x_data.append(x) self.y_datas.append(y) # update dataset with new datapoint if saving if self.is_saving(): yield self.data_vault.add([x]+y) for curve, y_data in zip(self.curves,zip(*self.y_datas)): # update data curve curve.setData(self.x_data,y_data) # indicate successful step returnValue(True) def is_optimizing(self): return self.optimizing def is_saving(self): return self.saving def is_returning(self): return self.returning # fit data to gaussian to find input value that optimizes output and set input to that value @inlineCallbacks def optimize_input(self): x_arr = np.array(self.x_data) y_arr = np.array(zip(*self.y_datas)[self.optimize_axis]) params = self.estimate_gaussian_parameters( x_arr,y_arr ) try: params, _ = curve_fit( self.gaussian, x_arr, y_arr, params ) except RuntimeError: pass x_fit = np.linspace(x_arr.min(),x_arr.max(),FIT_POINTS) self.fit_curve.setData( x_fit, self.gaussian(x_fit,*params) ) if self.fit_curve not in self.listDataItems(): self.show_fit() input = int(np.round(params[0])) if self.checking_optimize: result = QtGui.QMessageBox.question( self.__parent, 'check optimize', 'is optimize result of %d ok?' % input, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if result == QtGui.QMessageBox.No: message_box = QtGui.QMessageBox(self.__parent) click_button = message_box.addButton('click',QtGui.QMessageBox.AcceptRole) enter_button = message_box.addButton('enter',QtGui.QMessageBox.RejectRole) message_box.setText('specify how to enter location') message_box.setInformativeText('click location on graph or enter in value?') message_box.exec_() if message_box.clickedButton() == click_button: self.click_deferred = Deferred() input = yield self.click_deferred input = int(np.round(input)) else: new_input, result = QtGui.QInputDialog.getInt( self.__parent, 'enter location', 'location', input ) yield self.input.set_input(input) @staticmethod def gaussian(x,mean,std,amplitude,offset): return amplitude * np.exp(- 1. / 2. * np.square( ( x - mean ) / std) ) + offset @staticmethod def estimate_gaussian_parameters(x,y): min = y.min() max = y.max() offset = min amplitude = max - min mean_index = y.argmax() mean = x[mean_index] threshold = min + (max - min) / 2 right_estimate = None index = mean_index while True: if index == len(y): break if y[index] < threshold: right_estimate = abs(x[index] - mean) / 2.355 * 2 index += 1 left_estimate = None index = mean_index while True: if index < 0: break if y[index] < threshold: left_estimate = abs(x[index] - mean) / 2.355 * 2 index -= 1 if right_estimate is None and left_estimate is None: std = abs(x[len(y)/2]-x[0]) elif right_estimate is None: std = left_estimate elif left_estimate is None: std = right_estimate else: std = ( left_estimate + right_estimate ) / 2. return (mean,std,amplitude,offset)
def set_scan_items(self): scan = self.scan outputs = scan[OUTPUT] if type(outputs) is dict: outputs = [outputs] if self.is_saving(): # get labrad connection cxn = yield connectAsync() # get handle to data vault data_vault = cxn.data_vault # list of folders (trunk to leaf) for dataset directory save_dir = scan.get(SAVE_DIR,[]) # go to scans dir in dv yield data_vault.cd(data_vault_dir+save_dir,True) independent_variables = [ '%s [%s]' % ( scan[INPUT].get(NAME,'input'), scan[INPUT].get(UNITS,'arb') ) ] dependent_variables = [ '%s [%s]' % ( output.get(NAME,'output'), output.get(UNITS,'arb') ) for output in outputs ] save_name = scan.get(SAVE_NAME,None) default_name = text=scan.get(NAME,'') if save_name is None: save_name, result = QtGui.QInputDialog.getText( self.__parent, 'enter dataset name', 'enter title for data vault dataset', text = default_name ) if not result: save_name = default_name # create new dataset yield data_vault.new( str(save_name), independent_variables, dependent_variables ) # make note of dataset creation yield data_vault.add_parameter( 'time', get_datetime() ) self.data_vault = data_vault # instantiate scan input object self.input = INPUTS[ scan[INPUT][CLASS] ]( **mangle(scan[INPUT].get(ARGS,{})) ) # note initial position if we are planning to return to it after scan if self.is_returning(): self._return_input = yield self.input._get_input() # instantiate scan output object self.outputs = [ OUTPUTS[ output[CLASS] ]( **mangle(output.get(ARGS,{})) ) for output in outputs ] # intialize x and y values self.x_data = [] self.y_datas = [] # clear any stuff that happens to be in plot (TODO: do we ever scan the same object twice?) for item in self.allChildItems(): self.removeItem(item) # if optimizing or have multiple sources, \ # add legend to distinguish different sources if self.is_optimizing() or len(outputs) > 1: self.addLegend() if self.is_optimizing(): # initialize fit curve self.fit_curve = PlotDataItem( name='fit (%s)' % outputs[ self.optimize_axis ].get( NAME, 'output %d' % (self.optimize_axis+1) ), pen={'color':'BBB','width':2} ) # initialize data curves self.curves = [ self.plot( name=output.get(NAME,'output %d' % (index + 1)), pen=None, symbolSize=5, symbolPen=None, symbolBrush=('F55','5F5','55F','FF5','5FF','F5F')[index % 6] ) for index, output in enumerate(outputs) ]
def make_hst( self, curr_min=0.69 ) : # If no spectrum has been loaded, clear any existing histograms # and abort. if ( self.core.fc_spec is None ) : self.rset_hst( ) return # Use the spectral data to compute new axis-limits. self.make_lim( ) # Generate a step function for each look direction associated # with this widget. self.stp = array( [ step( self.core.fc_spec['vel_cen'][self.c] , self.core.fc_spec['vel_del'][self.c] , self.core.fc_spec['curr'][self.c][d]) for d in range(self.core.fc_spec['n_dir']) ]) stp_pnt = array( [ array( self.stp[d]\ .calc_pnt( lev_min=curr_min ) ) for d in range( self.core.fc_spec['n_dir'] ) ] ) self.stp_x = stp_pnt[:,0,:] self.stp_y = stp_pnt[:,1,:] self.asp_x = log10( self.stp_x ) if ( self.log_x ) else \ self.stp_x self.asp_y = log10( self.stp_y ) if ( self.log_y ) else \ self.stp_y # Adjust the individual axes to the new limits. for i in range( self.n_plt_x ) : self.axs_x[i].setRange( self.alm_x[0], self.alm_x[1] ) for j in range( self.n_plt_y ) : self.axs_y[j].setRange( self.alm_y[0], self.alm_y[1] ) # For each plot in the grid, adjust its limits, add a histogram, # and add a direction label. for d in range( min( self.core.fc_spec['n_dir'], self.n_plt ) ) : # Determine the location of this plot within the grid # layout. j = self.calc_ind_j( d ) i = self.calc_ind_i( d ) # If this plot does not exist, move onto the next one. if ( self.plt[j,i] is None ) : continue # If a histogram already exists for this plot, remove # and delete it. if ( self.hst[j,i] is not None ) : self.plt[j,i].removeItem( self.hst[j,i] ) self.hst[j,i] = None # Clear this plot's label of text. self.lbl[j,i].setText( '' ) # Adjust this plot's limits and then move it's label in # response. self.plt[j,i].setRange( xRange=self.alm_x, yRange=self.alm_y, padding=0. ) self.lbl[j,i].setPos( self.alm_x[1], self.alm_y[1] ) # Update this plot's label with appropriate text # indicating the pointing direction. r_alt = round( self.core.fc_spec['elev'][self.c] ) r_dir = round( self.core.fc_spec['azim'][self.c][d]) txt = ( u'({0:+.0f}\N{DEGREE SIGN}, ' + u'{1:+.0f}\N{DEGREE SIGN})' ).format( r_alt, r_dir ) self.lbl[j,i].setText( txt, color=(0,0,0) ) #self.lbl[j,i].setFont( self.fnt ) # Generate the histogram for the data from this look # direction and display it in the plot. self.hst[j,i] = PlotDataItem( self.asp_x[d,:], self.asp_y[d,:], pen=self.pen_hst ) self.plt[j,i].addItem( self.hst[j,i] )
def chng_pnt( self, t, p, b, sel_bin, sel_alt=None ) : # If no spectrum has been loaded, abort. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # If this point already exists, remove it from its plot and # delete it. if ( self.pnt[t,p,b] is not None ) : self.plt[t,p].removeItem( self.pnt[t,p,b] ) self.pnt[t,p,b] = None # If this point was not selected (based on both its primary and # secondary states), return (since there's nothing more to be # done). if ( not sel_bin or self.core.pl_spec_arr[self.n]['psd'][t][p][b] == 0) : return # Determine the "d" index corresponding to this look direction. d = p + ( t * self.n_plt_x ) # Computed the adjusted point location in the "ViewBox". if ( self.log_x ) : ax = log10( self.core.pl_spec_arr[self.n]['vel_cen'][b] ) else : ax = self.core.pl_spec_arr[self.n]['vel_cen'][b] if ( self.log_y ) : ay = log10( self.core.pl_spec_arr[self.n]['psd'][t][p][b] ) else : ay = self.core.pl_spec_arr[self.n]['psd'][t][p][b] # Select the color for the point (i.e., the brush and pen used # to render it) based on whether or not this datum's look # direction has been selected and whether or not the primary and # secondary selection states match. # if ( sel_bin == sel_alt ) : pen = self.pen_pnt_c brush = self.bsh_pnt_c # else : # pen = self.pen_pnt_y # brush = self.bsh_pnt_y # else : # pen = self.pen_pnt_r # brush = self.bsh_pnt_r # Select the symbol based on the values of the primary and # secondary selection states. # Note. At this point in the code, at least one of these two # states must be "True" since this -- when both states # are "False", this function returns before it reaches # this point. if ( sel_bin ) : symbol = 'o' else : symbol = 't' # Create, store, and add this selection point to the plot. if ( self.core.app.res_lo ) : size = 3 else : size = 6 self.pnt[t,p,b] = PlotDataItem( [ax], [ay], symbol=symbol, symbolSize=size, symbolPen=pen, symbolBrush=brush ) self.plt[t,p].addItem( self.pnt[t,p,b] )
def chng_pnt( self, j, i, b, sel_bin, sel_dir=True, sel_alt=None ) : # If this point already exists, remove it from its plot and # delete it. if ( self.pnt[j,i,b] is not None ) : self.plt[j,i].removeItem( self.pnt[j,i,b] ) self.pnt[j,i,b] = None # If the user gave no alternative selection state for this # datum, use the primary state for the secondary state. sel_alt = sel_bin if ( sel_alt is None ) else sel_alt # If this point was not selected (based on both its primary and # secondary states), return (since there's nothing more to be # done). if ( ( not sel_bin ) and ( not sel_alt ) ) : return # Determine the "d" index corresponding to this look direction. d = self.calc_ind_d( j, i ) # Computed the adjusted point location in the "ViewBox". if ( self.log_x ) : ax = log10( self.core.fc_spec['vel_cen'][self.c][b] ) else : ax = self.core.fc_spec['vel_cen'][self.c][b] if ( self.log_y ) : ay = log10( self.core.fc_spec['curr'][self.c][d][b] ) else : ay = self.core.fc_spec['curr'][self.c][d][b] # Select the color for the point (i.e., the brush and pen used # to render it) based on whether or not this datum's look # direction has been selected and whether or not the primary and # secondary selection states match. if ( sel_dir ) : if ( sel_bin == sel_alt ) : pen = self.pen_pnt_c brush = self.bsh_pnt_c else : pen = self.pen_pnt_y brush = self.bsh_pnt_y else : pen = self.pen_pnt_r brush = self.bsh_pnt_r # Select the symbol based on the values of the primary and # secondary selection states. # Note. At this point in the code, at least one of these two # states must be "True" since this -- when both states # are "False", this function returns before it reaches # this point. if ( sel_bin ) : if ( sel_alt ) : symbol = 's' else : symbol = 'o' else : symbol = 't' # Create, store, and add this selection point to the plot. if ( self.core.app.res_lo ) : size = 3 else : size = 6 self.pnt[j,i,b] = PlotDataItem( [ax], [ay], symbol=symbol, symbolSize=size, symbolPen=pen, symbolBrush=brush ) self.plt[j,i].addItem( self.pnt[j,i,b] )
class imMobilize(QtWidgets.QWidget): def __init__(self, parent=None, *args): # run the widget, get the form QtWidgets.QWidget.__init__(self, parent, *args) self.ui = Ui_Form() self.ui.setupUi(self) os.chdir("D:\\") self.working_directory_selected = False """ ============================================================== Connecting the buttons and labels in the serial control group ============================================================== """ self.arduino = Arduino() # populate serial available combobox self.update_serial_available() # connect scan button self.ui.buttonSerialScan.clicked.connect(self.update_serial_available) # connect connect/disconnect button self.ui.buttonSerialConnect.clicked.connect( self.serial_connect_disconnect) # try: # self.serial_connect_disconnect() # except: # QtWidgets.QMessageBox.warning(self, "No controller found", "Could not connect to a suitable controller \n Connect Manually.") self.ui.lineeditWriteToSerial.editingFinished.connect( self.write_to_serial) self.ui.buttonWriteToSerial.clicked.connect(self.write_to_serial) self.ui.checkBoxReadSerialLive.clicked.connect(self.listen_to_serial) self.logged_temperature = np.array([]) self.temp_plot_xvals = np.array([]) """ ===================================================================== Connecting the buttons and controls in the light stim controls group ===================================================================== """ # connect the save_stim button self.ui.buttonSaveStim.clicked.connect(self.save_lightstim) # Style the three sliders (color the handles) # self.ui.sliderRed.setStyleSheet("QSlider::handle:vertical {background-color: red; border: 1px outset; border-radius: 3px;}") # self.ui.sliderGreen.setStyleSheet("QSlider::handle:vertical {background-color: lime; border: 1px outset; border-radius: 3px;}") # self.ui.sliderBlue.setStyleSheet("QSlider::handle:vertical {background-color: cyan; border: 1px outset; border-radius: 3px;}") self.ui.toggleWhiteColor.valueChanged.connect( self.toggle_lightstim_type) self.toggle_lightstim_type() """ ==================================================================== Connecting buttons and controls in vibration stimuli group ==================================================================== """ self.ui.buttonSaveVibrationStim.clicked.connect( self.save_vibration_stim) """ ===================================================================== Connecting the buttons and controls in the stimuli manager group ===================================================================== """ self.Stims = StimuliManager(arduino=self.arduino) self.set_experiment_view() self.set_lightstim_name_lineedit() self.set_vibrationstim_name_lineedit() self.ui.buttonDeleteSelectedStim.clicked.connect( self.delete_selected_stim) self.ui.buttonDeleteAllStims.clicked.connect(self.delete_all_stims) self.ui.buttonLoadStimulusProfile.clicked.connect(self.load_stimuli) self.ui.buttonSaveStimulusProfile.clicked.connect(self.save_stimuli) """ ===================================================================== Connecting the buttons and controls in the MetaData entry group ===================================================================== """ self.ui.buttonSetWorkingDirectory.clicked.connect( self.set_working_directory) self.ui.labelMetaDataDrugName.setVisible(False) self.ui.lineeditMetaDataDrugName.setVisible(False) self.ui.labelMetaDataGenetics.setVisible(False) self.ui.lineeditMetaDataGenetics.setVisible(False) self.ui.spinBoxExperimentDurationMinutes.valueChanged.connect( self.set_experiment_view) self.ui.spinBoxExperimentDurationSeconds.valueChanged.connect( self.set_experiment_view) self.ui.checkBoxExperimentAutonaming.clicked.connect( self.set_experiment_autonaming) self.set_experiment_autonaming() self.experiment_live = False self.ui.buttonStartExperiment.clicked.connect(self.start_experiment) self.path = os.curdir self.experiment_name = self.ui.lineeditExperimentName.text() self.experiment_path = os.path.join(self.path, "Exp_" + self.experiment_name) """ ====================================================================== Connecting buttons and controls to the camera manager group ====================================================================== """ self.detect_cameras() self.ui.buttonCameraConnectDisconnect.clicked.connect( self.camera_connect_disconnect) self.ui.buttonCameraPreview.clicked.connect(self.toggle_preview) self.ui.buttonScanForCameras.clicked.connect(self.detect_cameras) self.ui.spinBoxFramerate.valueChanged.connect( self.set_camera_framerate) for x in range(-2, -12, -1): self.ui.comboboxCameraExposure.addItem(str(2**x)) self.ui.comboboxCameraExposure.currentTextChanged.connect( self.set_camera_exposure) self.ui.sliderCameraBrightness.sliderMoved.connect( self.set_camera_brightness) self.ui.sliderCameraGamma.sliderMoved.connect(self.set_camera_gamma) self.ui.buttonCameraResetProperties.clicked.connect( self.reset_camera_properties) #This is for IR light, so actually belongs to arduino, but it is located here in the GUI. self.ui.sliderIRLight.sliderReleased.connect(self.set_IR_light) """ ====================================================================== Connecting buttons and controls to the video manager ====================================================================== """ self.set_autonaming(True) self.ui.buttonSetPath.clicked.connect(self.set_path) self.ui.checkboxAutoNaming.toggled.connect(self.set_autonaming) self.ui.buttonRecordVideo.clicked.connect(self.record_video) def detect_cameras(self): self.ui.comboBoxConnectedCameras.clear() for ii in range(3): cap = cv2.VideoCapture(ii) if not cap.isOpened(): pass else: cam = "Camera " + str(ii + 1) self.ui.comboBoxConnectedCameras.addItem(cam) def camera_connect_disconnect(self): if not hasattr(self, "cam") or not self.cam.cap.isOpened(): camera_number = int(self.ui.comboBoxConnectedCameras.currentText(). split(" ")[1]) - 1 self.cam = Camera(camera=camera_number) if self.cam.cap.isOpened(): self.ui.groupBoxCameraControls.setEnabled(True) self.ui.groupBoxVideoControls.setEnabled(True) self.ui.comboBoxConnectedCameras.setEnabled(False) self.ui.labelCameraConnectionStatus.setText( "Connected to Camera " + str(camera_number + 1)) self.ui.labelCameraConnectionStatus.setStyleSheet( "color: green") self.ui.buttonCameraConnectDisconnect.setText("Disconnect") self.ui.buttonCameraConnectDisconnect.setStyleSheet( "color: red") t = self.ui.comboboxCameraExposure.findText( str(2**(self.cam.exposure))) self.ui.comboboxCameraExposure.setCurrentIndex(t) self.ui.sliderCameraBrightness.setValue(self.cam.brightness) self.ui.labelCameraBrighness.setNum(self.cam.brightness) self.ui.sliderCameraGamma.setValue(self.cam.gamma * 10) self.ui.labelCameraGamma.setNum(self.cam.gamma) self.ui.sliderCameraGamma.setEnabled(False) else: self.toggle_preview(False) self.cam.stop() self.cam.cap.release() self.ui.buttonCameraPreview.setChecked(False) self.ui.groupBoxCameraControls.setEnabled(False) self.ui.groupBoxVideoControls.setEnabled(False) self.ui.comboBoxConnectedCameras.setEnabled(True) self.ui.buttonCameraConnectDisconnect.setText("Connect") self.ui.buttonCameraConnectDisconnect.setStyleSheet("color: black") self.ui.labelCameraConnectionStatus.setText( "Status: Not Connected") self.ui.labelCameraConnectionStatus.setStyleSheet("color: black") def toggle_lightstim_type(self): val = self.ui.toggleWhiteColor.value() if val == 1: self.lightStimType = "White" self.ui.labelLightStimTypeLED.setEnabled(False) self.ui.labelLightStimTypeWhite.setEnabled(True) self.ui.widgetLEDSliders.setEnabled(False) self.ui.toggleWhiteColor.setStyleSheet( "QSlider::handle:horizontal {background-color: rgba(255,255,255,255); border: 2px outset; width: 10px; height: 10px; border-radius: 5px;}" "QSlider::groove:horizontal {height: 10px; width: 30px; background-color: rgba(255, 0,0, 100); border-radius: 5px; border: 1px solid;}" ) self.ui.sliderRed.setStyleSheet( "QSlider::handle:vertical {background-color: grey; border: 1px outset; border-radius: 3px;}" ) self.ui.sliderGreen.setStyleSheet( "QSlider::handle:vertical {background-color: grey; border: 1px outset; border-radius: 3px;}" ) self.ui.sliderBlue.setStyleSheet( "QSlider::handle:vertical {background-color: grey; border: 1px outset; border-radius: 3px;}" ) if val == 0: self.lightStimType = "LED" self.ui.labelLightStimTypeLED.setEnabled(True) self.ui.labelLightStimTypeWhite.setEnabled(False) self.ui.widgetLEDSliders.setEnabled(True) self.ui.toggleWhiteColor.setStyleSheet( "QSlider::handle:horizontal {background-color: rgba(255,100,0,100); border: 2px outset; width: 10px; height: 10px; border-radius: 5px;}" "QSlider::groove:horizontal {height: 10px; width: 30px; background-color: rgba(255, 255, 255,100); border-radius: 5px; border: 1px solid;}" ) self.ui.sliderRed.setStyleSheet( "QSlider::handle:vertical {background-color: red; border: 1px outset; border-radius: 3px;}" ) self.ui.sliderGreen.setStyleSheet( "QSlider::handle:vertical {background-color: lime; border: 1px outset; border-radius: 3px;}" ) self.ui.sliderBlue.setStyleSheet( "QSlider::handle:vertical {background-color: cyan; border: 1px outset; border-radius: 3px;}" ) def set_experiment_view(self): self.ui.graphicsView.clear() plot = PlotDataItem(pen="k") duration = (self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value() xs = np.linspace(0, duration, 2) ys = [1, 1] plot.setData(xs, ys) self.ui.graphicsView.addItem(plot) for ii in range(len(self.Stims.df)): start = self.Stims.df.time_on.iloc[ii] stop = self.Stims.df.time_off.iloc[ii] if self.Stims.df.message_on.iloc[ii].startswith("w"): box = LinearRegionItem(values=(start, stop), brush=(255, 255, 250, 230), movable=False) self.ui.graphicsView.addItem(box) elif self.Stims.df.message_on.iloc[ii].startswith("n"): on = self.Stims.df.message_on.iloc[ii][1:] r = int(on[:3]) g = int(on[3:6]) b = int(on[6:]) box = LinearRegionItem(values=(start, stop), brush=(r, g, b, 50), movable=False) self.ui.graphicsView.addItem(box) elif self.Stims.df.message_on.iloc[ii].startswith("v"): box = LinearRegionItem(values=(start, stop), brush="k", movable=False) self.ui.graphicsView.addItem(box) self.ui.comboBoxSelectStimId.clear() for stim_id in set(self.Stims.df.id): self.ui.comboBoxSelectStimId.addItem(stim_id) # def checkStimSafeguard(self): # if self.ui.checkboxDirectStim.isChecked() is False: # self.ui.listwidgetAllStims.itemDoubleClicked.disconnect(self.single_stim) # elif self.ui.checkboxDirectStim.isChecked(): # self.ui.listwidgetAllStims.itemDoubleClicked.connect(self.single_stim) def update_serial_available(self): """Scans the available comports and updates the combobox with the resulst""" self.ui.comboboxSerialAvailable.clear() self.arduino.scan_comports() for port in list(self.arduino.port_dict.keys()): self.ui.comboboxSerialAvailable.addItem(port) def serial_connect_disconnect(self): """Connects to selected serial if disconnected and vice versa""" if self.ui.buttonSerialConnect.text().lower() == "connect": port = self.ui.comboboxSerialAvailable.currentText() self.arduino.connect(port) if self.arduino.ser.isOpen(): self.ui.labelSerialConnected.setText("Connected: " + self.arduino.port) self.ui.labelSerialConnected.setStyleSheet("color: green") self.ui.buttonSerialConnect.setText("Disconnect") self.ui.checkBoxReadSerialLive.setEnabled(True) self.ui.sliderIRLight.setEnabled(True) elif self.ui.buttonSerialConnect.text().lower() == "disconnect": self.ui.checkBoxReadSerialLive.setChecked(False) self.arduino.disconnect() if self.arduino.ser.isOpen() == False: self.ui.labelSerialConnected.setText("Status: Not connected") self.ui.labelSerialConnected.setStyleSheet("color: black") self.ui.buttonSerialConnect.setText("Connect") self.ui.checkBoxReadSerialLive.setEnabled(False) self.ui.checkBoxReadSerialLive.setChecked(False) self.ui.sliderIRLight.setEnabled(False) def listen_to_serial(self): """Starts a thread that listens on the self.Arduino.ser serial connection and updates the GUI with incoming messages""" if self.ui.checkBoxReadSerialLive.isChecked(): self.ui.graphicsViewSerial.clear() self.temperature_plot = PlotDataItem(pen=(0, 153, 153)) self.temperature_plot_2 = PlotDataItem(pen=(255, 128, 0)) self.temperature_plot.setDownsampling(auto=True, method="mean") self.temperature_plot_2.setDownsampling(auto=True, method="mean") self.ui.graphicsViewSerial.addItem(self.temperature_plot) self.ui.graphicsViewSerial.addItem(self.temperature_plot_2) t = Thread(target=self.start_listening, args=()) t.start() def start_listening(self): """To be started in separate thread: listens to Serial port and updates gui via separate method if new message comes in""" self.arduino.ser.flushInput() self.logged_temperature = np.array([]) self.logged_temperature_2 = np.array([]) self.logged_temperature_time = np.array([]) start = time.time() while self.ui.checkBoxReadSerialLive.isChecked( ) and self.arduino.ser.isOpen(): if self.arduino.ser.in_waiting > 0: message = self.arduino.ser.readline().decode() elapsed_time = time.time() - start self.update_serial_display(message, np.round(elapsed_time, 2)) else: time.sleep(0.01) else: pass def update_serial_display(self, message, elapsed_time): temp1, temp2 = message.split(" ") self.ui.labelSerialLiveIncoming.setText(str(elapsed_time)) self.ui.labelSerialLiveTemperature.setText(message) temp1 = float(temp1) temp2 = float(temp2) self.logged_temperature_time = np.hstack( [self.logged_temperature_time, elapsed_time]) self.logged_temperature = np.hstack([self.logged_temperature, temp1]) self.logged_temperature_2 = np.hstack( [self.logged_temperature_2, temp2]) self.temperature_plot.setData(x=self.logged_temperature_time, y=self.logged_temperature) self.temperature_plot_2.setData(x=self.logged_temperature_time, y=self.logged_temperature_2) def write_to_serial(self): """Send message in the lineEdit widget to the serial port""" message = self.ui.lineeditWriteToSerial.text() self.arduino.write(message) self.ui.lineeditWriteToSerial.clear() def set_lightstim_name_lineedit(self): c = 1 while "LightStim" + str(len(self.Stims.df) + c) in self.Stims.df.id: c += 1 newname = "LightStim" + str(len(self.Stims.df) + c) self.ui.lineeditLightStimName.setText(newname) def save_lightstim(self): """Takes the current settings in the lightstim box and adds them to stim manager""" start_time = self.ui.spinboxStimStart.value() stop_time = self.ui.spinboxStimDuration.value() + start_time stim_id = self.ui.lineeditLightStimName.text() if self.lightStimType == "LED": start_message = "n" for slider in [ self.ui.sliderRed, self.ui.sliderGreen, self.ui.sliderBlue ]: start_message += str(slider.value()).zfill(3) stop_message = "nC" elif self.lightStimType == "White": start_message = "wS" stop_message = "wC" self.Stims.add_stimulus(start_time, stop_time, start_message, stop_message, stim_id) self.set_lightstim_name_lineedit() self.ui.comboBoxSelectStimId.clear() stim_ids = list(set(self.Stims.df.id)) stim_ids.sort() for stim_id in stim_ids: self.ui.comboBoxSelectStimId.addItem(stim_id) self.set_experiment_view() def set_vibrationstim_name_lineedit(self): c = 1 while "VibrationStim" + str(len(self.Stims.df) + c) in self.Stims.df.id: c += 1 newname = "VibrationStim" + str(len(self.Stims.df) + c) self.ui.lineeditVibrationStimName.setText(newname) def save_vibration_stim(self): """takes the current settings in the vibration stim box and adds it to the stim manager""" start_time = self.ui.spinBoxVibrationStart.value() duration = self.ui.spinBoxVibrationDuration.value() freq = self.ui.spinBoxVibrationFrequency.value() start_message = "v" + str(freq).zfill(3) + str(int( duration * 1000)).zfill(4) stop_message = "" stim_id = self.ui.lineeditVibrationStimName.text() self.Stims.add_stimulus(start_time, start_time + duration, start_message, stop_message, stim_id) self.set_vibrationstim_name_lineedit() self.ui.comboBoxSelectStimId.clear() stim_ids = list(set(self.Stims.df.id)) stim_ids.sort() for stim_id in stim_ids: self.ui.comboBoxSelectStimId.addItem(stim_id) self.set_experiment_view() def delete_selected_stim(self): stim_id = self.ui.comboBoxSelectStimId.currentText() self.Stims.delete_stimulus(stim_id) self.set_experiment_view() def delete_all_stims(self): self.Stims.delete_all_stims() self.set_experiment_view() def load_stimuli(self): file = QtWidgets.QFileDialog.getOpenFileName(self, "Select a Stimuli File") file = file[0] if os.path.exists(file) and file.endswith(".txt"): df = pd.read_csv(file, delimiter="\t") self.Stims.df = df self.set_experiment_view() elif not file: pass else: QtWidgets.QMessageBox.warning(self, "Invalid Filename", "Invalid Stimulus File selected.") def save_stimuli(self): filename_selected = False while not filename_selected: filename = QtWidgets.QFileDialog.getSaveFileName( self, "Save Stimuli file as")[0] if not filename: break else: if not filename.endswith(".txt"): filename += ".txt" self.Stims.df.to_csv(filename, sep="\t") filename_selected = True def toggle_preview(self, event): if event: self.cam.preview() self.ui.buttonCameraPreview.setText("Stop") self.ui.buttonCameraPreview.setStyleSheet("color: red") else: self.ui.buttonCameraPreview.setText("Preview") self.ui.buttonCameraPreview.setStyleSheet("color: Black") self.cam.stop() def set_autonaming(self, bool): if bool: self.ui.lineeditVideoName.setText( time.strftime("%Y%m%d_%H%M%S_video")) def set_experiment_autonaming(self): if self.ui.checkBoxExperimentAutonaming.isChecked(): name = time.strftime("%Y%m%d_%H%M%S") name += "_" name += str(self.ui.spinboxCrowdsize.value()) name += "_" name += str(self.ui.spinBoxExperimentDurationMinutes.value()) + "m" name += str( self.ui.spinBoxExperimentDurationSeconds.value()) + "s_" if self.ui.checkboxMetaDataDrugs.isChecked(): name += self.ui.lineeditMetaDataDrugName.text() + "_" else: name += "None_" if self.ui.checkboxMetaDataGenetics.isChecked(): name += self.ui.lineeditMetaDataGenetics.text() + "_" else: name += "None_" if len(self.Stims.df) > 0: name += "Light" else: name += "None" self.ui.lineeditExperimentName.setText(name) else: pass def set_camera_framerate(self, fps): self.cam.framerate = fps # if self.cam.do_gamma == False: # self.ui.sliderCameraGamma.setVisible(False) # self.ui.labelCameraGamma.setVisible(False) # else: # self.ui.sliderCameraGamma.setVisible(True) # self.ui.labelCameraGamma.setVisible(True) def set_camera_brightness(self, brightness): self.cam.brightness = brightness def set_camera_gamma(self, gamma): gamma = gamma / 10 self.cam.gamma = gamma self.ui.labelCameraGamma.setNum(gamma) def set_camera_exposure(self, exp): # If set exposure is longer than framerate allows, then adjust framerate exp = float(exp) if exp > (1 / self.cam.framerate): print( "\n WARNING: Adjusting framerate to accomodate for exposure \n" ) # self.set_camera_framerate(1 / exp) self.ui.spinBoxFramerate.setValue(int(1 / exp)) exp = np.log2(exp) self.cam.exposure = exp def set_IR_light(self): val = self.ui.sliderIRLight.value() self.arduino.write("i" + str(val).zfill(3)) sys.stdout.write('\n IR Light set to {}. {}% of power'.format( val, (val / 255) * 100)) def set_path(self): self.path = QtGui.QFileDialog.getExistingDirectory() print(self.path) def set_working_directory(self): self.working_directory_selected = False while not self.working_directory_selected: self.path = QtGui.QFileDialog.getExistingDirectory() if os.path.exists(self.path): os.chdir(self.path) self.working_directory_selected = True else: q = QtWidgets.QMessageBox.question( self, "No path selected", "Do you wish to not select a path? \n Path then defaults to D:\\" ) if q == QtWidgets.QMessageBox.Yes: self.path = "D:\\" self.working_directory_selected = True def reset_camera_properties(self): self.cam.brightness = 0 self.ui.sliderCameraBrightness.setValue(0) self.ui.labelCameraBrighness.setNum(0) self.cam.exposure = -5.0 t = self.ui.comboboxCameraExposure.findText(str(2**-5)) self.ui.comboboxCameraExposure.setCurrentIndex(t) self.cam.gamma = 1 self.ui.sliderCameraGamma.setValue(10) self.ui.labelCameraGamma.setNum(1) self.cam.framerate = 30 self.ui.spinBoxFramerate.setValue(30) def record_video(self, event): if event: self.ui.buttonRecordVideo.setText("Stop") self.ui.buttonRecordVideo.setStyleSheet("color:red") self.ui.groupBoxCameraControls.setEnabled(False) self.ui.groupBoxCameraConnection.setEnabled(False) if self.ui.checkboxAutoNaming.isChecked(): self.ui.lineeditVideoName.setText( time.strftime("%Y%m%d_%H%M" + "_experiment")) name = os.path.join(self.path, self.ui.lineeditVideoName.text()) duration = self.ui.spinBoxVideoTimeMinutes.value() * 60 duration += self.ui.spinBoxVideoTimeSeconds.value() preview = self.ui.checkBoxPreviewWhileRecording.isChecked() self.cam.video(name, duration, preview) t = Thread(target=self.wait_for_recording_end) t.start() else: self.ui.groupBoxCameraControls.setEnabled(True) self.ui.groupBoxCameraConnection.setEnabled(True) self.ui.buttonRecordVideo.setText("Record") self.ui.buttonRecordVideo.setStyleSheet("color:Black") self.cam.stop() def wait_for_recording_end(self): time.sleep(0.1) while self.cam.alive == True: time.sleep(0.1) else: self.record_video(False) # self.ui.buttonRecordVideo.setChecked(False) # """ ========================================================================================== METHODS TO RUN AN ENTIRE EXPERIMENT ========================================================================================== """ def start_experiment(self, event): if event: if not hasattr(self, "cam"): QtWidgets.QMessageBox.warning( self, "Not Connected Warning", "No open connection with Camera") self.ui.buttonStartExperiment.setChecked(False) elif not self.cam.cap.isOpened(): QtWidgets.QMessageBox.warning( self, "Not Connected Warning", "No open connection with Camera") self.ui.buttonStartExperiment.setChecked(False) elif not self.arduino.connected: QtWidgets.QMessageBox.warning( self, "Not Connected Warning", "No open connection with Controller") self.ui.buttonStartExperiment.setChecked(False) else: if not self.working_directory_selected: QtWidgets.QMessageBox.warning( self, "No valid working directory", "Select a directory to save your experiment") self.set_working_directory() self.experiment_live = True self.ui.buttonStartExperiment.setStyleSheet( 'color: rgba(255,0,0,255)') self.ui.buttonStartExperiment.setText('Interrupt') self.set_experiment_autonaming() self.ui.widgetMetaData.setEnabled(False) self.experiment_name = self.ui.lineeditExperimentName.text() self.experiment_path = os.path.join( self.path, "Exp_" + self.experiment_name) if not os.path.exists( self.experiment_path) or not os.path.isdir( self.experiment_path): os.mkdir(self.experiment_path) if self.ui.checkBoxReadSerialLive.isChecked(): self.ui.checkBoxReadSerialLive.setChecked(False) self.ui.checkBoxReadSerialLive.setChecked(True) self.listen_to_serial() duration = ( self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value() preview = self.ui.checkBoxPreviewWhileRecording.isChecked() self.cam.video( os.path.join(self.experiment_path, self.experiment_name), duration, preview) self.Stims.start_stimuli() t = Thread(target=self.wait_for_experiment_end, args=()) t.start() else: self.experiment_live = False self.cam.stop() self.ui.checkBoxReadSerialLive.setChecked(False) self.ui.buttonStartExperiment.setStyleSheet("color: Black") self.ui.buttonStartExperiment.setText("Start Experiment") df = pd.DataFrame() df["date"] = [time.strftime("%Y%m%d")] df["time"] = [time.strftime("%H%M%S")] df["duration"] = [ (self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value() ] df["drugs"] = [self.ui.lineeditMetaDataDrugName.text()] df["genetics"] = [self.ui.lineeditMetaDataGenetics.text()] df["age"] = [self.ui.spinboxAge] df["framerate"] = [self.cam.framerate] df["dechorionated"] = [ self.ui.checkboxMetaDataDechorionation.isChecked() ] df["exposture"] = [ float(self.ui.comboboxCameraExposure.currentText()) ] df["gamma"] = [self.cam.gamma] df["brightness"] = [self.cam.brightness] df["infrared"] = [self.ui.sliderIRLight.value()] df.to_csv(os.path.join(self.experiment_path, "metadata.txt"), sep="\t") self.Stims.df.to_csv(os.path.join(self.experiment_path, "stimuli_profile.txt"), sep="\t") df = pd.DataFrame(np.hstack([ self.logged_temperature_time.reshape(-1, 1), self.logged_temperature.reshape(-1, 1), self.logged_temperature_2.reshape(-1, 1) ]), columns=["time", "temperature", "temperature2"]) df.set_index("time", inplace=True) df.to_csv(os.path.join(self.experiment_path, "logged_temperatures.txt"), sep="\t") self.ui.widgetMetaData.setEnabled(True) def wait_for_experiment_end(self): time.sleep(0.2) # Give camera a chance to start. while self.cam.alive: time.sleep(0.2) else: if self.experiment_live: self.start_experiment(False) self.ui.buttonStartExperiment.setChecked(False) # def start_experiment(self): # # if self.experiment_live: # self.experiment_live = False # self.cam.stop() # self.ui.checkBoxReadSerialLive.setChecked(False) # self.ui.buttonStartExperiment.setStyleSheet("color: Black") # self.ui.buttonStartExperiment.setText("Start Experiment") # # df = pd.DataFrame() # df["date"] = [time.strftime("%Y%m%d")] # df["time"] = [time.strftime("%H%M%S")] # df["duration"] = [(self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value()] # df["drugs"] = [self.ui.lineeditMetaDataDrugName.text()] # df["genetics"] = [self.ui.lineeditMetaDataGenetics.text()] # df["framerate"] = [self.cam.framerate] # df["dechorionated"] = [self.ui.checkboxMetaDataDechorionation.isChecked()] # df["exposture"] = [float(self.ui.comboboxCameraExposure.currentText())] # df["gamma"] = [self.cam.brightness] # df["brightness"] = [self.cam.brightness] # df["infrared"] = [self.ui.sliderIRLight.value] # # # df.to_csv(os.path.join(self.experiment_path, "metadata.txt"), sep="\t") # # self.Stims.df.to_csv(os.path.join(self.experiment_path, "stimuli_profile.txt"), sep="\t") # df = pd.DataFrame(np.hstack([self.logged_temperature_time.reshape(-1,1), self.logged_temperature.reshape(-1,1), self.logged_temperature_2.reshape(-1,1)]), columns = ["time", "temperature", "temperature2"]) # df.set_index("time", inplace=True) # df.to_csv(os.path.join(self.experiment_path, "logged_temperatures.txt"), sep="\t") # # # self.ui.groupboxMetaData.setEnabled(True) # # elif not self.experiment_live: # if not hasattr(self, "cam"): # QtWidgets.QMessageBox.warning(self, "Not Connected Warning", "No open connection with Camera or Controller") # elif self.cam.cap.isOpened() != True or self.arduino.ser.isOpen() != True: # QtWidgets.QMessageBox.warning(self, "Not Connected Warning", "No open connection with Camera or Controller") # else: # self.experiment_live = True # self.ui.buttonStartExperiment.setStyleSheet('color: rgba(255,0,0,255)') # self.ui.buttonStartExperiment.setText('Interrupt') # # self.set_experiment_autonaming() # self.ui.groupboxMetaData.setEnabled(False) # self.experiment_name = self.ui.lineeditExperimentName.text() # # self.experiment_path = os.path.join(self.path, "Exp_" + self.experiment_name) # if not os.path.exists(self.experiment_path) or not os.path.isdir(self.experiment_path): # os.mkdir(self.experiment_path) # # if self.ui.checkBoxReadSerialLive.isChecked(): # self.ui.checkBoxReadSerialLive.setChecked(False) # self.ui.checkBoxReadSerialLive.setChecked(True) # self.listen_to_serial() # # duration = (self.ui.spinBoxExperimentDurationMinutes.value() * 60) + self.ui.spinBoxExperimentDurationSeconds.value() # self.cam.video(os.path.join(self.experiment_path, self.experiment_name), duration) # self.Stims.start_stimuli() # t = Thread(target=self.wait_for_experiment_end, args=()) # t.start() # def wait_for_experiment_end(self): # time.sleep(0.2) # Give camera a chance to start. # while self.cam.alive: # time.sleep(0.1) # else: # if self.experiment_live: # self.start_experiment() def closeEvent(self, event): QtWidgets.QMessageBox.warning(self, "Closing", "Nothing you can do about it") self.arduino.ser.close() self.cam.cap.release() event.accept() print("yay")
def __init__(self, name, parent=None): super(makeTimeseriesCurveNode, self).__init__(name, parent=parent, terminals={'df': {'io': 'in'}, 'pd.Series': {'io': 'out'}, 'Curve': {'io': 'out'}}, color=(150, 150, 250, 150)) self._plotRequired = False self.item = PlotDataItem(clipToView=False)
class PMTWidgetUI(QWidget): # waveforms_generated = pyqtSignal(object, object, list, int) SignalForContourScanning = pyqtSignal(int, int, int, np.ndarray, np.ndarray) MessageBack = pyqtSignal(str) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # os.chdir('./')# Set directory to current folder. self.setFont(QFont("Arial")) self.setMinimumSize(1200,850) self.setWindowTitle("PMTWidget") self.layout = QGridLayout(self) #------------------------Initiating class------------------- self.pmtTest = pmtimagingTest() self.pmtTest_contour = pmtimagingTest_contour() self.savedirectory = r'M:\tnw\ist\do\projects\Neurophotonics\Brinkslab\Data\Octoscope\pmt_image_default_dump' self.prefixtextboxtext = '_fromGalvoWidget' #************************************************************************************************************************************** #-------------------------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------GUI for PMT tab------------------------------------------------------------ #-------------------------------------------------------------------------------------------------------------------------------------- #************************************************************************************************************************************** pmtimageContainer = QGroupBox("PMT image") self.pmtimageLayout = QGridLayout() self.pmtvideoWidget = pg.ImageView() self.pmtvideoWidget.ui.roiBtn.hide() self.pmtvideoWidget.ui.menuBtn.hide() self.pmtvideoWidget.resize(400,400) self.pmtimageLayout.addWidget(self.pmtvideoWidget, 0, 0) pmtroiContainer = QGroupBox("PMT ROI") self.pmtimageroiLayout = QGridLayout() self.pmt_roiwidget = pg.GraphicsLayoutWidget() self.pmt_roiwidget.resize(150,150) self.pmt_roiwidget.addLabel('ROI', row=0, col=0) # create ROI self.vb_2 = self.pmt_roiwidget.addViewBox(row=1, col=0, lockAspect=True, colspan=1) self.vb_2.name = 'ROI' self.pmtimgroi = pg.ImageItem() self.vb_2.addItem(self.pmtimgroi) #self.roi = pg.RectROI([20, 20], [20, 20], pen=(0,9)) #r1 = QRectF(0, 0, 895, 500) ROIpen = QPen() # creates a default pen ROIpen.setStyle(Qt.DashDotLine) ROIpen.setWidth(0.5) ROIpen.setBrush(QColor(0,161,255)) self.roi = pg.PolyLineROI([[0,0], [80,0], [80,80], [0,80]], closed=True, pen=ROIpen)#, maxBounds=r1 #self.roi.addScaleHandle([1,0], [1, 0]) self.roi.sigHoverEvent.connect(lambda: self.show_handle_num()) # update handle numbers self.pmtvb = self.pmtvideoWidget.getView() self.pmtimageitem = self.pmtvideoWidget.getImageItem() self.pmtvb.addItem(self.roi)# add ROIs to main image self.pmtimageroiLayout.addWidget(self.pmt_roiwidget, 0, 0) pmtimageContainer.setMinimumWidth(850) pmtroiContainer.setMaximumHeight(380) # pmtroiContainer.setMaximumWidth(300) pmtimageContainer.setLayout(self.pmtimageLayout) pmtroiContainer.setLayout(self.pmtimageroiLayout) #----------------------------Contour----------------------------------- pmtContourContainer = QGroupBox("Contour selection") pmtContourContainer.setFixedWidth(280) self.pmtContourLayout = QGridLayout() #contour_Description = QLabel("Handle number updates when parking mouse cursor upon ROI. Points in contour are divided evenly between handles.") #contour_Description.setStyleSheet('color: blue') #self.pmtContourLayout.addWidget(contour_Description,0,0) self.pmt_handlenum_Label = QLabel("Handle number: ") self.pmtContourLayout.addWidget(self.pmt_handlenum_Label,1,0) self.contour_strategy = QComboBox() self.contour_strategy.addItems(['Manual','Uniform']) self.pmtContourLayout.addWidget(self.contour_strategy, 1, 1) self.pointsinContour = QSpinBox(self) self.pointsinContour.setMinimum(1) self.pointsinContour.setMaximum(1000) self.pointsinContour.setValue(100) self.pointsinContour.setSingleStep(100) self.pmtContourLayout.addWidget(self.pointsinContour, 2, 1) self.pmtContourLayout.addWidget(QLabel("Points in contour:"), 2, 0) self.contour_samprate = QSpinBox(self) self.contour_samprate.setMinimum(0) self.contour_samprate.setMaximum(1000000) self.contour_samprate.setValue(50000) self.contour_samprate.setSingleStep(50000) self.pmtContourLayout.addWidget(self.contour_samprate, 3, 1) self.pmtContourLayout.addWidget(QLabel("Sampling rate:"), 3, 0) self.generate_contour_sacn = StylishQT.generateButton() self.pmtContourLayout.addWidget(self.generate_contour_sacn, 4, 1) self.generate_contour_sacn.clicked.connect(lambda: self.generate_contour()) self.do_contour_sacn = StylishQT.runButton("Contour") self.do_contour_sacn.setFixedHeight(32) self.pmtContourLayout.addWidget(self.do_contour_sacn, 5, 0) self.do_contour_sacn.clicked.connect(lambda:self.buttonenabled('contourscan', 'start')) self.do_contour_sacn.clicked.connect(lambda: self.measure_pmt_contourscan()) self.stopButton_contour = StylishQT.stop_deleteButton() self.stopButton_contour.setFixedHeight(32) self.stopButton_contour.clicked.connect(lambda:self.buttonenabled('contourscan', 'stop')) self.stopButton_contour.clicked.connect(lambda: self.stopMeasurement_pmt_contour()) self.stopButton_contour.setEnabled(False) self.pmtContourLayout.addWidget(self.stopButton_contour, 5, 1) pmtContourContainer.setLayout(self.pmtContourLayout) #----------------------------Control----------------------------------- controlContainer = QGroupBox("Galvo Scanning Panel") controlContainer.setFixedWidth(280) self.controlLayout = QGridLayout() self.pmt_fps_Label = QLabel("Per frame: ") self.controlLayout.addWidget(self.pmt_fps_Label, 5, 0) self.saveButton_pmt = StylishQT.saveButton() self.saveButton_pmt.clicked.connect(lambda: self.saveimage_pmt()) self.controlLayout.addWidget(self.saveButton_pmt, 5, 1) self.startButton_pmt = StylishQT.runButton("") self.startButton_pmt.setFixedHeight(32) self.startButton_pmt.setCheckable(True) self.startButton_pmt.clicked.connect(lambda:self.buttonenabled('rasterscan', 'start')) self.startButton_pmt.clicked.connect(lambda: self.measure_pmt()) self.controlLayout.addWidget(self.startButton_pmt, 6, 0) self.stopButton = StylishQT.stop_deleteButton() self.stopButton.setFixedHeight(32) self.stopButton.clicked.connect(lambda:self.buttonenabled('rasterscan', 'stop')) self.stopButton.clicked.connect(lambda: self.stopMeasurement_pmt()) self.stopButton.setEnabled(False) self.controlLayout.addWidget(self.stopButton, 6, 1) #-----------------------------------Galvo scanning------------------------------------------------------------------------ self.textboxAA_pmt = QSpinBox(self) self.textboxAA_pmt.setMinimum(0) self.textboxAA_pmt.setMaximum(1000000) self.textboxAA_pmt.setValue(500000) self.textboxAA_pmt.setSingleStep(100000) self.controlLayout.addWidget(self.textboxAA_pmt, 1, 1) self.controlLayout.addWidget(QLabel("Sampling rate:"), 1, 0) #self.controlLayout.addWidget(QLabel("Galvo raster scanning : "), 1, 0) self.textbox1B_pmt = QSpinBox(self) self.textbox1B_pmt.setMinimum(-10) self.textbox1B_pmt.setMaximum(10) self.textbox1B_pmt.setValue(3) self.textbox1B_pmt.setSingleStep(1) self.controlLayout.addWidget(self.textbox1B_pmt, 2, 1) self.controlLayout.addWidget(QLabel("Volt range:"), 2, 0) self.Scanning_pixel_num_combobox = QSpinBox(self) self.Scanning_pixel_num_combobox.setMinimum(0) self.Scanning_pixel_num_combobox.setMaximum(1000) self.Scanning_pixel_num_combobox.setValue(500) self.Scanning_pixel_num_combobox.setSingleStep(244) self.controlLayout.addWidget(self.Scanning_pixel_num_combobox, 3, 1) self.controlLayout.addWidget(QLabel("Pixel number:"), 3, 0) self.textbox1H_pmt = QSpinBox(self) self.textbox1H_pmt.setMinimum(1) self.textbox1H_pmt.setMaximum(20) self.textbox1H_pmt.setValue(1) self.textbox1H_pmt.setSingleStep(1) self.controlLayout.addWidget(self.textbox1H_pmt, 4, 1) self.controlLayout.addWidget(QLabel("average over:"), 4, 0) controlContainer.setLayout(self.controlLayout) #---------------------------Set tab1 layout--------------------------- # pmtmaster = QGridLayout() self.layout.addWidget(pmtimageContainer, 0,0,3,1) self.layout.addWidget(pmtroiContainer,1,1) self.layout.addWidget(pmtContourContainer,2,1) self.layout.addWidget(controlContainer,0,1) # self.layout.setLayout(pmtmaster) #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& #-------------------------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------Functions for TAB 'PMT'--------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------------- #************************************************************************************************************************************** def buttonenabled(self, button, switch): if button == 'rasterscan': if switch == 'start': self.startButton_pmt.setEnabled(False) self.stopButton.setEnabled(True) elif switch == 'stop': self.startButton_pmt.setEnabled(True) self.stopButton.setEnabled(False) elif button == 'contourscan': if switch == 'start': #disable start button and enable stop button self.do_contour_sacn.setEnabled(False) self.stopButton_contour.setEnabled(True) elif switch == 'stop': self.do_contour_sacn.setEnabled(True) self.stopButton_contour.setEnabled(False) def measure_pmt(self): self.Daq_sample_rate_pmt = int(self.textboxAA_pmt.value()) # Voltage settings, by default it's equal range square. self.Value_voltXMax = self.textbox1B_pmt.value() self.Value_voltXMin = self.Value_voltXMax*-1 Value_voltYMin = self.Value_voltXMin Value_voltYMax = self.Value_voltXMax self.Value_xPixels = int(self.Scanning_pixel_num_combobox.value()) Value_yPixels = self.Value_xPixels self.averagenum =int(self.textbox1H_pmt.value()) Totalscansamples = self.pmtTest.setWave(self.Daq_sample_rate_pmt, self.Value_voltXMin, self.Value_voltXMax, Value_voltYMin, Value_voltYMax, self.Value_xPixels, Value_yPixels, self.averagenum) time_per_frame_pmt = Totalscansamples/self.Daq_sample_rate_pmt ScanArrayXnum=int((Totalscansamples/self.averagenum)/Value_yPixels) #r1 = QRectF(500, 500, ScanArrayXnum, int(Value_yPixels)) #self.pmtimageitem.setRect(r1) self.pmtTest.pmtimagingThread.measurement.connect(self.update_pmt_Graphs) #Connecting to the measurement signal self.pmt_fps_Label.setText("Per frame: %.4f s" % time_per_frame_pmt) self.pmtTest.start() def measure_pmt_contourscan(self): self.Daq_sample_rate_pmt = int(self.contour_samprate.value()) self.pmtTest_contour.setWave_contourscan(self.Daq_sample_rate_pmt, self.handle_viewbox_coordinate_position_array_expanded_forDaq, self.contour_point_number) contour_freq = self.Daq_sample_rate_pmt/self.contour_point_number #r1 = QRectF(500, 500, ScanArrayXnum, int(Value_yPixels)) #self.pmtimageitem.setRect(r1) #self.pmtTest_contour.pmtimagingThread_contour.measurement.connect(self.update_pmt_Graphs) #Connecting to the measurement signal self.pmt_fps_Label.setText("Contour frequency: %.4f Hz" % contour_freq) self.pmtTest_contour.start() self.MessageToMainGUI('---!! Continuous contour scanning !!---'+'\n') def saveimage_pmt(self): Localimg = Image.fromarray(self.data_pmtcontineous) #generate an image object Localimg.save(os.path.join(self.savedirectory, 'PMT_'+ self.prefixtextboxtext + '_' +datetime.now().strftime('%Y-%m-%d_%H-%M-%S')+'.tif')) #save as tif #np.save(os.path.join(self.savedirectory, 'PMT'+ self.saving_prefix +datetime.now().strftime('%Y-%m-%d_%H-%M-%S')), self.data_pmtcontineous) def update_pmt_Graphs(self, data): """Update graphs.""" self.data_pmtcontineous = data self.pmtvideoWidget.setImage(data) self.pmtimgroi.setImage(self.roi.getArrayRegion(data, self.pmtimageitem), levels=(0, data.max())) # #self.pmtvideoWidget.update_pmt_Window(self.data_pmtcontineous) def show_handle_num(self): self.ROIhandles = self.roi.getHandles() self.ROIhandles_nubmer = len(self.ROIhandles) self.pmt_handlenum_Label.setText("Handle number: %.d" % self.ROIhandles_nubmer) def generate_contour(self): """ getLocalHandlePositions IS THE FUNCTION TO GRAP COORDINATES FROM IMAGEITEM REGARDLESS OF IMAGEITEM ZOOMING OR PANNING!!! """ self.ROIhandles = self.roi.getHandles() self.ROIhandles_nubmer = len(self.ROIhandles) self.contour_point_number = int(self.pointsinContour.value()) self.handle_scene_coordinate_position_raw_list = self.roi.getSceneHandlePositions() self.handle_local_coordinate_position_raw_list = self.roi.getLocalHandlePositions() self.Daq_sample_rate_pmt = int(self.contour_samprate.value()) # self.galvo_contour_label_1.setText("Points in contour: %.d" % self.contour_point_number) # self.galvo_contour_label_2.setText("Sampling rate: %.d" % self.Daq_sample_rate_pmt) #put scene positions into numpy array self.handle_scene_coordinate_position_array = np.zeros((self.ROIhandles_nubmer, 2))# n rows, 2 columns for i in range(self.ROIhandles_nubmer): self.handle_scene_coordinate_position_array[i] = np.array([self.handle_scene_coordinate_position_raw_list[i][1].x(), self.handle_scene_coordinate_position_raw_list[i][1].y()]) if self.contour_strategy.currentText() == 'Manual': #Interpolation self.point_num_per_line = int(self.contour_point_number/self.ROIhandles_nubmer) self.Interpolation_number = self.point_num_per_line-1 # try to initialize an array then afterwards we can append on it #self.handle_scene_coordinate_position_array_expanded = np.array([[self.handle_scene_coordinate_position_array[0][0], self.handle_scene_coordinate_position_array[0][1]], [self.handle_scene_coordinate_position_array[1][0], self.handle_scene_coordinate_position_array[1][1]]]) # -------------------------------------------------------------------------Interpolation from first to last---------------------------------------------------------------------------- for i in range(self.ROIhandles_nubmer-1): self.Interpolation_x_diff = self.handle_scene_coordinate_position_array[i+1][0] - self.handle_scene_coordinate_position_array[i][0] self.Interpolation_y_diff = self.handle_scene_coordinate_position_array[i+1][1] - self.handle_scene_coordinate_position_array[i][1] self.Interpolation_x_step = self.Interpolation_x_diff/self.point_num_per_line self.Interpolation_y_step = self.Interpolation_y_diff/self.point_num_per_line Interpolation_temp = np.array([[self.handle_scene_coordinate_position_array[i][0], self.handle_scene_coordinate_position_array[i][1]], [self.handle_scene_coordinate_position_array[i+1][0], self.handle_scene_coordinate_position_array[i+1][1]]]) for j in range(self.Interpolation_number): Interpolation_temp=np.insert(Interpolation_temp,1,[self.handle_scene_coordinate_position_array[i+1][0] - (j+1)*self.Interpolation_x_step,self.handle_scene_coordinate_position_array[i+1][1] - (j+1)*self.Interpolation_y_step],axis = 0) Interpolation_temp = np.delete(Interpolation_temp, 0, 0) if i == 0: self.handle_scene_coordinate_position_array_expanded = Interpolation_temp else: self.handle_scene_coordinate_position_array_expanded=np.append(self.handle_scene_coordinate_position_array_expanded, Interpolation_temp, axis=0) #self.handle_scene_coordinate_position_array_expanded=np.delete(self.handle_scene_coordinate_position_array_expanded, 0, 0) # Interpolation between last and first self.Interpolation_x_diff = self.handle_scene_coordinate_position_array[0][0] - self.handle_scene_coordinate_position_array[-1][0] self.Interpolation_y_diff = self.handle_scene_coordinate_position_array[0][1] - self.handle_scene_coordinate_position_array[-1][1] self.Interpolation_x_step = self.Interpolation_x_diff/self.point_num_per_line self.Interpolation_y_step = self.Interpolation_y_diff/self.point_num_per_line Interpolation_temp = np.array([[self.handle_scene_coordinate_position_array[-1][0], self.handle_scene_coordinate_position_array[-1][1]], [self.handle_scene_coordinate_position_array[0][0], self.handle_scene_coordinate_position_array[0][1]]]) for j in range(self.Interpolation_number): Interpolation_temp=np.insert(Interpolation_temp,1,[self.handle_scene_coordinate_position_array[0][0] - (j+1)*self.Interpolation_x_step,self.handle_scene_coordinate_position_array[0][1] - (j+1)*self.Interpolation_y_step],axis = 0) Interpolation_temp = np.delete(Interpolation_temp, 0, 0) #Interpolation_temp = np.flip(Interpolation_temp, 0) self.handle_scene_coordinate_position_array_expanded=np.append(self.handle_scene_coordinate_position_array_expanded, Interpolation_temp, axis=0) #self.handle_scene_coordinate_position_array_expanded=np.delete(self.handle_scene_coordinate_position_array_expanded, 0, 0) #----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self.handle_viewbox_coordinate_position_array_expanded = np.zeros((self.contour_point_number, 2))# n rows, 2 columns # Maps from scene coordinates to the coordinate system displayed inside the ViewBox for i in range(self.contour_point_number): qpoint_Scene = QPoint(self.handle_scene_coordinate_position_array_expanded[i][0], self.handle_scene_coordinate_position_array_expanded[i][1]) qpoint_viewbox = self.pmtvb.mapSceneToView(qpoint_Scene) self.handle_viewbox_coordinate_position_array_expanded[i] = np.array([qpoint_viewbox.x(),qpoint_viewbox.y()]) #print(self.handle_scene_coordinate_position_array) #print(self.handle_scene_coordinate_position_array_expanded) #print(self.handle_viewbox_coordinate_position_array_expanded) constants = HardwareConstants() '''Transform into Voltages to galvos''' '''coordinates in the view box(handle_viewbox_coordinate_position_array_expanded_x) are equivalent to voltages sending out''' if self.Value_xPixels == 500: if self.Value_voltXMax == 3: # for 500 x axis, the real ramp region sits around 52~552 out of 0~758 self.handle_viewbox_coordinate_position_array_expanded[:,0] = ((self.handle_viewbox_coordinate_position_array_expanded[:,0])/500)*6-3 #(self.handle_viewbox_coordinate_position_array_expanded[:,0]-constants.pmt_3v_indentation_pixels) self.handle_viewbox_coordinate_position_array_expanded[:,1] = ((self.handle_viewbox_coordinate_position_array_expanded[:,1])/500)*6-3 self.handle_viewbox_coordinate_position_array_expanded = np.around(self.handle_viewbox_coordinate_position_array_expanded, decimals=3) # shape into (n,) and stack self.handle_viewbox_coordinate_position_array_expanded_x = np.resize(self.handle_viewbox_coordinate_position_array_expanded[:,0],(self.contour_point_number,)) self.handle_viewbox_coordinate_position_array_expanded_y = np.resize(self.handle_viewbox_coordinate_position_array_expanded[:,1],(self.contour_point_number,)) self.handle_viewbox_coordinate_position_array_expanded_forDaq = np.vstack((self.handle_viewbox_coordinate_position_array_expanded_x,self.handle_viewbox_coordinate_position_array_expanded_y)) print(self.handle_viewbox_coordinate_position_array_expanded) '''Speed and acceleration check''' #for i in range(self.contour_point_number): # speed_between_points = ((self.handle_viewbox_coordinate_position_array_expanded_x[i+1]-self.handle_viewbox_coordinate_position_array_expanded_x[i])**2+(self.handle_viewbox_coordinate_position_array_expanded_y[i+1]-self.handle_viewbox_coordinate_position_array_expanded_y[i])**2)**(0.5) self.Daq_sample_rate_pmt = int(self.contour_samprate.value()) time_gap = 1/self.Daq_sample_rate_pmt contour_x_speed = np.diff(self.handle_viewbox_coordinate_position_array_expanded_x)/time_gap contour_y_speed = np.diff(self.handle_viewbox_coordinate_position_array_expanded_y)/time_gap contour_x_acceleration = np.diff(contour_x_speed)/time_gap contour_y_acceleration = np.diff(contour_y_speed)/time_gap constants = HardwareConstants() speedGalvo = constants.maxGalvoSpeed #Volt/s aGalvo = constants.maxGalvoAccel #Acceleration galvo in volt/s^2 print(np.amax(abs(contour_x_speed))) print(np.amax(abs(contour_y_speed))) print(np.amax(abs(contour_x_acceleration))) print(np.amax(abs(contour_y_acceleration))) print(str(np.mean(abs(contour_x_speed)))+' and mean y speed:'+str(np.mean(abs(contour_y_speed)))) print(str(np.mean(abs(contour_x_acceleration)))+' and mean y acceleration:'+str(np.mean(abs(contour_y_acceleration)))) if speedGalvo > np.amax(abs(contour_x_speed)) and speedGalvo > np.amax(abs(contour_y_speed)): print('Contour speed is OK') self.MessageToMainGUI('Contour speed is OK'+'\n') else: QMessageBox.warning(self,'OverLoad','Speed too high!',QMessageBox.Ok) if aGalvo > np.amax(abs(contour_x_acceleration)) and aGalvo > np.amax(abs(contour_y_acceleration)): print('Contour acceleration is OK') self.MessageToMainGUI('Contour acceleration is OK'+'\n') else: QMessageBox.warning(self,'OverLoad','Acceleration too high!',QMessageBox.Ok) if self.contour_strategy.currentText() == 'Uniform': # Calculate the total distance self.total_distance = 0 for i in range(self.ROIhandles_nubmer): if i != (self.ROIhandles_nubmer-1): Interpolation_x_diff = self.handle_scene_coordinate_position_array[i+1][0] - self.handle_scene_coordinate_position_array[i][0] Interpolation_y_diff = self.handle_scene_coordinate_position_array[i+1][1] - self.handle_scene_coordinate_position_array[i][1] distance_vector = (Interpolation_x_diff**2+Interpolation_y_diff**2)**(0.5) self.total_distance = self.total_distance + distance_vector else: Interpolation_x_diff = self.handle_scene_coordinate_position_array[0][0] - self.handle_scene_coordinate_position_array[-1][0] Interpolation_y_diff = self.handle_scene_coordinate_position_array[0][1] - self.handle_scene_coordinate_position_array[-1][1] distance_vector = (Interpolation_x_diff**2+Interpolation_y_diff**2)**(0.5) self.total_distance = self.total_distance + distance_vector self.averaged_uniform_step = self.total_distance/self.contour_point_number print(self.averaged_uniform_step) print(self.handle_scene_coordinate_position_array) for i in range(self.ROIhandles_nubmer): if i == 0: Interpolation_x_diff = self.handle_scene_coordinate_position_array[i+1][0] - self.handle_scene_coordinate_position_array[i][0] Interpolation_y_diff = self.handle_scene_coordinate_position_array[i+1][1] - self.handle_scene_coordinate_position_array[i][1] distance_vector = (Interpolation_x_diff**2+Interpolation_y_diff**2)**(0.5) num_of_Interpolation = distance_vector//self.averaged_uniform_step #Interpolation_remaining = distance_vector%self.averaged_uniform_step self.Interpolation_remaining_fornextround = self.averaged_uniform_step*(1-(distance_vector/self.averaged_uniform_step-num_of_Interpolation)) print('Interpolation_remaining_fornextround: '+str(self.Interpolation_remaining_fornextround)) self.Interpolation_x_step = Interpolation_x_diff/(distance_vector/self.averaged_uniform_step) self.Interpolation_y_step = Interpolation_y_diff/(distance_vector/self.averaged_uniform_step) Interpolation_temp = np.array([[self.handle_scene_coordinate_position_array[i][0], self.handle_scene_coordinate_position_array[i][1]], [self.handle_scene_coordinate_position_array[i+1][0], self.handle_scene_coordinate_position_array[i+1][1]]]) for j in range(int(num_of_Interpolation)): Interpolation_temp=np.insert(Interpolation_temp,-1,[self.handle_scene_coordinate_position_array[i][0] + (j+1)*self.Interpolation_x_step,self.handle_scene_coordinate_position_array[i+1][1] + (j+1)*self.Interpolation_y_step],axis = 0) Interpolation_temp = np.delete(Interpolation_temp,-1,axis=0) self.handle_scene_coordinate_position_array_expanded_uniform = Interpolation_temp elif i != (self.ROIhandles_nubmer-1): Interpolation_x_diff = self.handle_scene_coordinate_position_array[i+1][0] - self.handle_scene_coordinate_position_array[i][0] Interpolation_y_diff = self.handle_scene_coordinate_position_array[i+1][1] - self.handle_scene_coordinate_position_array[i][1] distance_vector = (Interpolation_x_diff**2+Interpolation_y_diff**2)**(0.5) num_of_Interpolation = (distance_vector-self.Interpolation_remaining_fornextround)//self.averaged_uniform_step print('Interpolation_remaining_fornextround: '+str(self.Interpolation_remaining_fornextround)) if self.Interpolation_remaining_fornextround != 0: self.Interpolation_remaining_fornextround_x =Interpolation_x_diff/(distance_vector/self.Interpolation_remaining_fornextround)#(self.Interpolation_remaining_fornextround/distance_vector)*Interpolation_x_diff self.Interpolation_remaining_fornextround_y =Interpolation_y_diff/(distance_vector/self.Interpolation_remaining_fornextround)#(self.Interpolation_remaining_fornextround/distance_vector)*Interpolation_y_diff else: self.Interpolation_remaining_fornextround_x = 0 self.Interpolation_remaining_fornextround_y = 0 # Reset the starting point Interpolation_x_diff = self.handle_scene_coordinate_position_array[i+1][0] - self.handle_scene_coordinate_position_array[i][0] - self.Interpolation_remaining_fornextround_x Interpolation_y_diff = self.handle_scene_coordinate_position_array[i+1][1] - self.handle_scene_coordinate_position_array[i][1] - self.Interpolation_remaining_fornextround_y self.Interpolation_x_step = Interpolation_x_diff/((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step) self.Interpolation_y_step = Interpolation_y_diff/((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step) Interpolation_temp = np.array([[self.handle_scene_coordinate_position_array[i][0]+self.Interpolation_remaining_fornextround_x, self.handle_scene_coordinate_position_array[i][1]+self.Interpolation_remaining_fornextround_y], [self.handle_scene_coordinate_position_array[i+1][0], self.handle_scene_coordinate_position_array[i+1][1]]]) for j in range(int(num_of_Interpolation)): Interpolation_temp=np.insert(Interpolation_temp,-1,[self.handle_scene_coordinate_position_array[i][0]+self.Interpolation_remaining_fornextround_x + (j+1)*self.Interpolation_x_step,self.handle_scene_coordinate_position_array[i][1]+\ self.Interpolation_remaining_fornextround_y + (j+1)*self.Interpolation_y_step],axis = 0) Interpolation_temp = np.delete(Interpolation_temp,-1,axis=0) self.handle_scene_coordinate_position_array_expanded_uniform=np.append(self.handle_scene_coordinate_position_array_expanded_uniform, Interpolation_temp, axis=0) self.Interpolation_remaining_fornextround = self.averaged_uniform_step*(1-((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step-num_of_Interpolation)) else: # connect the first and the last Interpolation_x_diff = self.handle_scene_coordinate_position_array[0][0] - self.handle_scene_coordinate_position_array[-1][0] Interpolation_y_diff = self.handle_scene_coordinate_position_array[0][1] - self.handle_scene_coordinate_position_array[-1][1] distance_vector = (Interpolation_x_diff**2+Interpolation_y_diff**2)**(0.5) num_of_Interpolation = (distance_vector-self.Interpolation_remaining_fornextround)//self.averaged_uniform_step #self.Interpolation_remaining_fornextround = self.averaged_uniform_step*(1-((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step-num_of_Interpolation)) self.Interpolation_remaining_fornextround_x =(self.Interpolation_remaining_fornextround/distance_vector)*Interpolation_x_diff self.Interpolation_remaining_fornextround_y =(self.Interpolation_remaining_fornextround/distance_vector)*Interpolation_y_diff # Reset the starting point Interpolation_x_diff = self.handle_scene_coordinate_position_array[0][0] - self.handle_scene_coordinate_position_array[i][0] + self.Interpolation_remaining_fornextround_x Interpolation_y_diff = self.handle_scene_coordinate_position_array[0][1] - self.handle_scene_coordinate_position_array[i][1] + self.Interpolation_remaining_fornextround_y self.Interpolation_x_step = Interpolation_x_diff/((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step) self.Interpolation_y_step = Interpolation_y_diff/((distance_vector-self.Interpolation_remaining_fornextround)/self.averaged_uniform_step) Interpolation_temp = np.array([[self.handle_scene_coordinate_position_array[-1][0]+self.Interpolation_remaining_fornextround_x, self.handle_scene_coordinate_position_array[-1][1]+self.Interpolation_remaining_fornextround_y], [self.handle_scene_coordinate_position_array[0][0], self.handle_scene_coordinate_position_array[0][1]]]) for j in range(int(num_of_Interpolation)): Interpolation_temp=np.insert(Interpolation_temp,-1,[self.handle_scene_coordinate_position_array[-1][0]+self.Interpolation_remaining_fornextround_x + (j+1)*self.Interpolation_x_step,self.handle_scene_coordinate_position_array[-1][1]+\ self.Interpolation_remaining_fornextround_y + (j+1)*self.Interpolation_y_step],axis = 0) Interpolation_temp = np.delete(Interpolation_temp,-1,axis=0) self.handle_scene_coordinate_position_array_expanded_uniform=np.append(self.handle_scene_coordinate_position_array_expanded_uniform, Interpolation_temp, axis=0) print(self.handle_scene_coordinate_position_array_expanded_uniform) print(self.handle_scene_coordinate_position_array_expanded_uniform.shape) #----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self.handle_viewbox_coordinate_position_array_expanded = np.zeros((self.contour_point_number, 2))# n rows, 2 columns # Maps from scene coordinates to the coordinate system displayed inside the ViewBox for i in range(self.contour_point_number): qpoint_Scene = QPoint(self.handle_scene_coordinate_position_array_expanded_uniform[i][0], self.handle_scene_coordinate_position_array_expanded_uniform[i][1]) qpoint_viewbox = self.pmtvb.mapSceneToView(qpoint_Scene) self.handle_viewbox_coordinate_position_array_expanded[i] = np.array([qpoint_viewbox.x(),qpoint_viewbox.y()]) #print(self.handle_scene_coordinate_position_array) #print(self.handle_scene_coordinate_position_array_expanded) #print(self.handle_viewbox_coordinate_position_array_expanded) '''Transform into Voltages to galvos''' constants = HardwareConstants() if self.Value_xPixels == 500: if self.Value_voltXMax == 3: # for 500 x axis, the real ramp region sits around 52~552 out of 0~758 self.handle_viewbox_coordinate_position_array_expanded[:,0] = ((self.handle_viewbox_coordinate_position_array_expanded[:,0])/500)*6-3 #self.handle_viewbox_coordinate_position_array_expanded[:,0]-constants.pmt_3v_indentation_pixels self.handle_viewbox_coordinate_position_array_expanded[:,1] = ((self.handle_viewbox_coordinate_position_array_expanded[:,1])/500)*6-3 self.handle_viewbox_coordinate_position_array_expanded = np.around(self.handle_viewbox_coordinate_position_array_expanded, decimals=3) # shape into (n,) and stack self.handle_viewbox_coordinate_position_array_expanded_x = np.resize(self.handle_viewbox_coordinate_position_array_expanded[:,0],(self.contour_point_number,)) self.handle_viewbox_coordinate_position_array_expanded_y = np.resize(self.handle_viewbox_coordinate_position_array_expanded[:,1],(self.contour_point_number,)) self.handle_viewbox_coordinate_position_array_expanded_forDaq = np.vstack((self.handle_viewbox_coordinate_position_array_expanded_x,self.handle_viewbox_coordinate_position_array_expanded_y)) print(self.handle_viewbox_coordinate_position_array_expanded) '''Speed and acceleration check''' #for i in range(self.contour_point_number): # speed_between_points = ((self.handle_viewbox_coordinate_position_array_expanded_x[i+1]-self.handle_viewbox_coordinate_position_array_expanded_x[i])**2+(self.handle_viewbox_coordinate_position_array_expanded_y[i+1]-self.handle_viewbox_coordinate_position_array_expanded_y[i])**2)**(0.5) self.Daq_sample_rate_pmt = int(self.contour_samprate.value()) time_gap = 1/self.Daq_sample_rate_pmt contour_x_speed = np.diff(self.handle_viewbox_coordinate_position_array_expanded_x)/time_gap contour_y_speed = np.diff(self.handle_viewbox_coordinate_position_array_expanded_y)/time_gap contour_x_acceleration = np.diff(contour_x_speed)/time_gap contour_y_acceleration = np.diff(contour_y_speed)/time_gap constants = HardwareConstants() speedGalvo = constants.maxGalvoSpeed #Volt/s aGalvo = constants.maxGalvoAccel #Acceleration galvo in volt/s^2 print(np.amax(abs(contour_x_speed))) print(np.amax(abs(contour_y_speed))) print(np.amax(abs(contour_x_acceleration))) print(np.amax(abs(contour_y_acceleration))) print(str(np.mean(abs(contour_x_speed)))+' and mean y speed:'+str(np.mean(abs(contour_y_speed)))) print(str(np.mean(abs(contour_x_acceleration)))+' and mean y acceleration:'+str(np.mean(abs(contour_y_acceleration)))) if speedGalvo > np.amax(abs(contour_x_speed)) and speedGalvo > np.amax(abs(contour_y_speed)): print('Contour speed is OK') self.MessageToMainGUI('Contour speed is OK'+'\n') if aGalvo > np.amax(abs(contour_x_acceleration)) and aGalvo > np.amax(abs(contour_y_acceleration)): print('Contour acceleration is OK') self.MessageToMainGUI('Contour acceleration is OK'+'\n') self.SignalForContourScanning.emit(self.contour_point_number, self.Daq_sample_rate_pmt, (1/int(self.contour_samprate.value())*1000)*self.contour_point_number, self.handle_viewbox_coordinate_position_array_expanded_x, self.handle_viewbox_coordinate_position_array_expanded_y) def generate_contour_for_waveform(self): self.contour_time = int(self.textbox1L.value()) self.time_per_contour = (1/int(self.contour_samprate.value())*1000)*self.contour_point_number repeatnum_contour = int(self.contour_time/self.time_per_contour) self.repeated_contoursamples_1 = np.tile(self.handle_viewbox_coordinate_position_array_expanded_x, repeatnum_contour) self.repeated_contoursamples_2 = np.tile(self.handle_viewbox_coordinate_position_array_expanded_y, repeatnum_contour) self.handle_viewbox_coordinate_position_array_expanded_forDaq_waveform = np.vstack((self.repeated_contoursamples_1,self.repeated_contoursamples_2)) return self.handle_viewbox_coordinate_position_array_expanded_forDaq_waveform def generate_galvos_contour_graphy(self): self.xlabelhere_galvos = np.arange(len(self.handle_viewbox_coordinate_position_array_expanded_forDaq_waveform[1,:]))/self.Daq_sample_rate_pmt self.PlotDataItem_galvos = PlotDataItem(self.xlabelhere_galvos, self.handle_viewbox_coordinate_position_array_expanded_forDaq_waveform[1,:]) self.PlotDataItem_galvos.setDownsampling(auto=True, method='mean') self.PlotDataItem_galvos.setPen('w') self.pw.addItem(self.PlotDataItem_galvos) self.textitem_galvos = pg.TextItem(text='Contour', color=('w'), anchor=(1, 1)) self.textitem_galvos.setPos(0, 5) self.pw.addItem(self.textitem_galvos) def MessageToMainGUI(self, text): self.MessageBack.emit(text) def stopMeasurement_pmt(self): """Stop the seal test.""" self.pmtTest.aboutToQuitHandler() def stopMeasurement_pmt_contour(self): """Stop the seal test.""" self.pmtTest_contour.aboutToQuitHandler() self.MessageToMainGUI('---!! Contour stopped !!---'+'\n') # def closeEvent(self, event): # # QtWidgets.QApplication.quit() # event.accept() '''