コード例 #1
0
ファイル: CameraInterface.py プロジェクト: ablot/acq4
 def makeGroup(self, dev, subdev):
     grp = DeviceTreeItemGroup.makeGroup(self, dev, subdev)
     if dev is self.device:
         bound = QtGui.QGraphicsPathItem(self.device.getBoundary(globalCoords=False))
         bound.setParentItem(grp)
         bound.setPen(pg.mkPen(40, 150, 150))
     return grp
コード例 #2
0
 def setRelativeDepth(self, depth):
     # adjust the apparent depth of the target
     dist = depth * 255 / 50e-6
     color = (np.clip(dist + 256, 0, 255), np.clip(256 - dist, 0, 255), 0)
     self.pen = pg.mkPen(color)
     self._picture = None
     self.update()
コード例 #3
0
ファイル: CameraInterface.py プロジェクト: travis-open/acq4
 def makeGroup(self, dev, subdev):
     grp = DeviceTreeItemGroup.makeGroup(self, dev, subdev)
     if dev is self.device:
         bound = QtGui.QGraphicsPathItem(self.device.getBoundary(globalCoords=False))
         bound.setParentItem(grp)
         bound.setPen(pg.mkPen(40, 150, 150))
     return grp
コード例 #4
0
 def paint(self, p, *args):
     p.setRenderHint(p.Antialiasing)
     w, h = self._pxLen
     p.setPen(pg.mkPen('y'))
     p.setBrush(pg.mkBrush(255, 255, 0, 100))
     p.scale(w, h)
     p.drawPath(self._path)
コード例 #5
0
    def addROI(self, roiType):
        pen = pg.mkPen(pg.intColor(len(self.ROIs)))
        center = self.view.viewRect().center()
        #print 'camerawindow.py: addROI:: ', self.view.viewPixelSize()
        size = [x * 50 for x in self.view.viewPixelSize()]
        if roiType == 'rect':
            roi = PlotROI(center, size)
        elif roiType == 'ellipse':
            roi = pg.EllipseROI(center, size, removable=True)
        elif roiType == 'polygon':
            pts = [
                center, center + pg.Point(0, size[1]),
                center + pg.Point(size[0], 0)
            ]
            roi = pg.PolyLineROI(pts, closed=True, removable=True)
        elif roiType == 'ruler':
            pts = [center, center + pg.Point(size[0], size[1])]
            roi = RulerROI(pts, removable=True)
        else:
            raise ValueError("Invalid ROI type %s" % roiType)

        roi.setZValue(40000)
        roi.setPen(pen)
        self.view.addItem(roi)
        plot = self.roiPlot.plot(pen=pen)
        self.ROIs.append({'roi': roi, 'plot': plot, 'vals': [], 'times': []})
        roi.sigRemoveRequested.connect(self.removeROI)
コード例 #6
0
ファイル: MapAnalyzer.py プロジェクト: ablot/acq4
 def __init__(self):
     pg.GraphicsObject.__init__(self)
     self.times = []
     self.yRange=(0.1, 0.2)
     self.xRange=[float('inf'), float('-inf')]
     self.pen = pg.mkPen(None)
     self.brush = pg.mkBrush((200,200,255,200))
コード例 #7
0
    def start(self, canvas, plot):
        """Add graphics items to *view* showing the path of the scanner.
        """
        self.clear()

        self.path = pg.PlotCurveItem()
        self.spot = QtGui.QGraphicsEllipseItem(QtCore.QRectF(-1, -1, 2, 2))
        self.spot.scale(1e-6, 1e-6)
        self.spot.setPen(pg.mkPen('y'))

        self.data = self.program.generatePositionArray()
        self.laserMask = self.program.generateLaserMask()
        self.lastTime = pg.ptime.time()
        self.index = 0
        self.sampleRate = self.program.sampleRate

        self.timeline = pg.InfiniteLine(angle=90)
        self.timeline.setZValue(100)

        if canvas is not None:
            canvas.addItem(self.path)
            canvas.addItem(self.spot)
        if plot is not None:
            self.plot = plot
            self.plotTimeline(plot)
            plot.addItem(self.timeline)

        self.timer.start(16)
コード例 #8
0
 def __init__(self):
     pg.GraphicsObject.__init__(self)
     self.times = []
     self.yRange = (0.1, 0.2)
     self.xRange = [float('inf'), float('-inf')]
     self.pen = pg.mkPen(None)
     self.brush = pg.mkBrush((200, 200, 255, 200))
コード例 #9
0
ファイル: CellCanvasItem.py プロジェクト: reneurossance/acq4
 def __init__(self, **opts):
     if 'scale' not in opts:
         opts['scale'] = [20e-6, 20e-6]
     item = QtGui.QGraphicsEllipseItem(-0.5, -0.5, 1., 1.)
     item.setPen(pg.mkPen((255, 255, 255)))
     item.setBrush(pg.mkBrush((0, 100, 255)))
     opts.setdefault('scalable', False)
     opts.setdefault('rotatable', False)
     CanvasItem.__init__(self, item, **opts)
     self.selectBox.addTranslateHandle([0.5, 0.5])
コード例 #10
0
 def paint(self, p, *args):
     p.setRenderHint(p.Antialiasing)
     w, h = self._pxLen
     # r = QtCore.QRectF(-w, -h, w*2, h*2)
     p.setPen(pg.mkPen('y'))
     p.setBrush(pg.mkBrush(255, 255, 0, 100))
     # p.drawEllipse(r)
     # p.drawLine(pg.Point(-w*2, 0), pg.Point(w*2, 0))
     # p.drawLine(pg.Point(0, -h*2), pg.Point(0, h*2))
     p.scale(w, h)
     p.drawPath(self._path)
コード例 #11
0
ファイル: rect.py プロジェクト: travis-open/acq4
    def paint(self, p, *args):
        p.setPen(pg.mkPen(0.3))

        #p.drawRect(self.boundingRect())  # causes artifacts at large scale
        br = self.boundingRect()
        # p.drawPolygon(QtGui.QPolygonF([br.topLeft(), br.topRight(), br.bottomRight(), br.bottomLeft()]))
        p.drawLine(br.topLeft(), br.topRight())
        p.drawLine(br.bottomLeft(), br.bottomRight())
        p.drawLine(br.topLeft(), br.bottomLeft())
        p.drawLine(br.bottomRight(), br.topRight())

        pg.ROI.paint(self, p, *args)
コード例 #12
0
ファイル: CellCanvasItem.py プロジェクト: ablot/acq4
 def __init__(self, **opts):
     if 'scale' not in opts:
         opts['scale'] = [20e-6, 20e-6]
         #opts['size'] = [20e-6, 20e-6]
         #opts['scale'] = [1., 1.]
     item = QtGui.QGraphicsEllipseItem(-0.5, -0.5, 1., 1.)
     item.setPen(pg.mkPen((255,255,255)))
     item.setBrush(pg.mkBrush((0,100,255)))
     opts['scalable'] = False
     opts['rotatable'] = False
     CanvasItem.__init__(self, item, **opts)
     self.selectBox.addTranslateHandle([0.5,0.5])
コード例 #13
0
ファイル: CameraWindow.py プロジェクト: ablot/acq4
 def addROI(self):
     pen = pg.mkPen(pg.intColor(len(self.ROIs)))
     center = self.view.viewRect().center()
     #print 'camerawindow.py: addROI:: ', self.view.viewPixelSize()
     size = [x*50 for x in self.view.viewPixelSize()]
     roi = PlotROI(center, size)
     roi.setZValue(40000)
     roi.setPen(pen)
     self.view.addItem(roi)
     plot = self.roiPlot.plot(pen=pen)
     self.ROIs.append({'roi': roi, 'plot': plot, 'vals': [], 'times': []})
     roi.sigRemoveRequested.connect(self.removeROI)
コード例 #14
0
    def __init__(self, pos, state=None):
        ROI.PolyLineROI.__init__(self, [[0, 0], [2, 0], [2, 1], [0, 1]],
                                 pos=pos,
                                 closed=True,
                                 pen=pg.mkPen(50, 50, 255, 200))

        ## don't let the user add handles to the sides, only to the top and bottom
        self.segments[0].setAcceptedMouseButtons(QtCore.Qt.NoButton)
        #self.segments[1].setAcceptedMouseButtons(QtCore.Qt.NoButton) ## there was a change in PolylineROI that affected the order of segments, so now 0 and 2 are the sides instead of 1 and 3 (2013.12.12)
        self.segments[2].setAcceptedMouseButtons(QtCore.Qt.NoButton)
        #self.segments[3].setAcceptedMouseButtons(QtCore.Qt.NoButton)

        if state is not None:
            self.setState(state)
コード例 #15
0
ファイル: Imager.py プロジェクト: song9206/acq4
    def paintEvent(self, event):
        p = QtGui.QPainter(self)
        brush = pg.mkBrush(0.0)
        p.fillRect(self.rect(), brush)

        center = self.rect().center()
        r = QtCore.QPoint(70, 30)
        self.cancelRect = QtCore.QRect(center-r, center+r)
        p.setPen(pg.mkPen(150, 0, 0))
        f = p.font()
        f.setPointSize(18)
        p.setFont(f)
        if self.cancelPressed:
            p.fillRect(self.cancelRect, pg.mkBrush(80, 0, 0))
        p.drawRect(self.cancelRect)
        p.drawText(self.cancelRect, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter, "Cancel")
        p.end()
コード例 #16
0
ファイル: __main__.py プロジェクト: ablot/acq4
def plotData():
    rate = 1e3
    nPts = 100
    plot.clear()

    params = {}
    paramSpace = sg.listSequences()
    for k in paramSpace:
        params[k] = range(len(paramSpace[k]))

    global seqPlots
    seqPlots = []
    SequenceRunner.runSequence(lambda p: seqPlots.append(sg.getSingle(rate, nPts, p)), params, params.keys())
    
    for i, w in enumerate(seqPlots):
        if w is not None:
            plot.plot(w, pen=pg.intColor(i, len(seqPlots)*1.5))

    data = sg.getSingle(rate, nPts)
    plot.plot(data, pen=pg.mkPen('w', width=2))
コード例 #17
0
def plotData():
    rate = 1e3
    nPts = 100
    plot.clear()

    params = {}
    paramSpace = sg.listSequences()
    for k in paramSpace:
        params[k] = range(len(paramSpace[k]))

    global seqPlots
    seqPlots = []
    SequenceRunner.runSequence(
        lambda p: seqPlots.append(sg.getSingle(rate, nPts, p)), params,
        list(params.keys()))

    for i, w in enumerate(seqPlots):
        if w is not None:
            plot.plot(w, pen=pg.intColor(i, len(seqPlots) * 1.5))

    data = sg.getSingle(rate, nPts)
    plot.plot(data, pen=pg.mkPen('w', width=2))
コード例 #18
0
    def paint(self, p, *args):
        p.setRenderHint(p.Antialiasing)
        px = self.pixelLength(pg.Point(1, 0))
        py = self.pixelLength(pg.Point(0, 1))
        w = 5 * px
        h = 5 * py
        r = QtCore.QRectF(-w, -h, w * 2, h * 2)
        p.setPen(pg.mkPen('y'))
        p.setBrush(pg.mkBrush(0, 0, 255, 100))
        p.drawEllipse(r)
        p.drawLine(pg.Point(-w * 2, 0), pg.Point(w * 2, 0))
        p.drawLine(pg.Point(0, -h * 2), pg.Point(0, h * 2))

        if self.label is not None:
            angle = self.labelAngle * np.pi / 180.
            pos = p.transform().map(QtCore.QPointF(
                0, 0)) + 15 * QtCore.QPointF(np.cos(angle), -np.sin(angle))
            p.resetTransform()
            p.drawText(QtCore.QRectF(pos.x() - 10,
                                     pos.y() - 10, 20, 20),
                       QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter,
                       self.label)
コード例 #19
0
ファイル: Scan.py プロジェクト: ablot/acq4
 def displayData(self, fh, plot, pen, evTime=None, eventFilter=None):
     """
     Display data for a single site in a plot--ephys trace, detected events
     Returns all items added to the plot.
     """
     pen = pg.mkPen(pen)
     
     items = []
     if isinstance(fh, basestring):
         fh = self.source()[fh]
     if fh.isDir():
         fh = self.dataModel.getClampFile(fh)
         
     ## plot all data, incl. events
     data = fh.read()['primary']
     data = fn.besselFilter(data, 4e3)
     pc = plot.plot(data, pen=pen, clear=False)
     items.append(pc)
     
     ## mark location of event if an event index was given
     if evTime is not None:
         #pos = float(index)/len(data)
         pos = evTime / data.xvals('Time')[-1]
         #print evTime, data.xvals('Time')[-1], pos
         #print index
         arrow = pg.CurveArrow(pc, pos=pos)
         plot.addItem(arrow)
         items.append(arrow)
         
     events = self.getEvents(fh)['events']
     
     if eventFilter is not None:
         events = eventFilter(events)
     
     ## draw ticks over all detected events
     if len(events) > 0:
         if 'fitTime' in events.dtype.names:
             times = events['fitTime']
             ticks = pg.VTickGroup(times, [0.9, 1.0], pen=pen)
             plot.addItem(ticks)
             items.append(ticks)
             #self.mapTicks.append(ticks)
             
         ## draw event fits
         evPen = pg.mkPen(pen)
         c = evPen.color()
         c.setAlpha(c.alpha()/2)
         evPen.setColor(c)
         for ev in events:
             time = ev['fitTime']
             try:
                 fitLen = ev['fitDecayTau']*ev['fitLengthOverDecay']
             except IndexError:
                 fitLen = ev['fitDecayTau']*4.
             x = np.linspace(time, time+fitLen, fitLen * 50e3)
             v = [ev['fitAmplitude'], ev['fitTime'], ev['fitRiseTau'], ev['fitDecayTau']]
             y = fn.pspFunc(v, x, risePower=2.0) + data[np.argwhere(data.xvals('Time')>time)[0]-1]
             evc = plot.plot(x, y, pen=evPen)
             evc.setZValue(pc.zValue()-100)
             
     return items
コード例 #20
0
ファイル: MapAnalyzer.py プロジェクト: ablot/acq4
 def setPen(self, pen):
     pen = pg.mkPen(pen)
     self.pen = pen
     for t in self.times:
         t.setPen(pen)
コード例 #21
0
    def __init__(self, dev, taskRunner):
        TaskGui.__init__(self, dev, taskRunner)
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        dm = getManager()
        self.targets = None
        self.items = {}
        self.haveCalibration = True   ## whether there is a calibration for the current combination of laser/optics
        self.currentOpticState = None
        self.currentCamMod = None
        self.displaySize = {}  ## maps (laser,opticState) : display size
                               ## since this setting is remembered for each objective.
        
        # Make sure DQ appears in this task
        daqName = dev.getDaqName()
        taskRunner.getDevice(daqName)
        
        ## Populate module/device lists, auto-select based on device defaults 
        self.defCam = None
        if 'defaultCamera' in self.dev.config:
            self.defCam = self.dev.config['defaultCamera']
        defLaser = None
        if 'defaultLaser' in self.dev.config:
            defLaser = self.dev.config['defaultLaser']
            
        daqDev = dev.getDaqName()
        self.daqUI = taskRunner.getDevice(daqDev)

        self.ui.cameraCombo.setTypes(['cameraModule'])
        self.ui.laserCombo.setTypes(['laser'])
        
        self.positionCtrlGroup = PositionCtrlGroup()
        self.positionCtrlGroup.sigAddNewRequested.connect(self.addPositionCtrl)
        self.ui.itemTree.setParameters(self.positionCtrlGroup, showTop=False)
        self.positionCtrlGroup.sigChildRemoved.connect(self.positionCtrlRemoved)
        self.ui.spotSequenceGroup.setCollapsed(True)
        self.ui.spotDisplayGroup.setCollapsed(True)
        
        self.scanProgram = ScanProgram()
        self.scanProgram.setDevices(scanner=self.dev)
        self.ui.programTree.setParameters(self.scanProgram.ctrlParameter(), showTop=False)

        ## Set up SpinBoxes
        self.ui.minTimeSpin.setOpts(dec=True, step=1, minStep=1e-3, siPrefix=True, suffix='s', bounds=[0, 50])
        self.ui.minDistSpin.setOpts(dec=True, step=1, minStep=1e-6, siPrefix=True, suffix='m', bounds=[0, 10e-3])
        self.ui.sizeSpin.setOpts(dec=True, step=1, minStep=1e-6, siPrefix=True, suffix='m', bounds=[1e-9, 1e-3])
        ## Create state group for saving/restoring state
        self.stateGroup = pg.WidgetGroup([
            (self.ui.cameraCombo,),
            (self.ui.laserCombo,),
            (self.ui.minTimeSpin, 'minTime'),
            (self.ui.minDistSpin, 'minDist'),
            (self.ui.simulateShutterCheck, 'simulateShutter'),
            (self.ui.sizeSpin, 'spotSize'),
            (self.ui.enablePosCtrlCheck, 'enablePosCtrl'),
            (self.ui.enableScanProgCheck, 'enableScanProg'),
        ])
        self.stateGroup.setState({'minTime': 10, 'minDist': 500e-6, 'sizeSpin':100e-6})
        self.tdPlot = self.ui.tdPlotWidget.plotItem
        self.tdPlot.setLabel('bottom', text="Distance", units='m')
        self.tdPlot.setLabel('left', text="Wait time", units='s')

        self.ui.scanProgramSplitter.setSizes([600, 100])
        self.ui.programTimeline.setDownsampling(True)
        ## Note we use lambda functions for all these clicks to strip out the arg sent with the signal
        
        self.ui.showPosCtrlCheck.toggled.connect(self.showPosCtrls)
        self.ui.cameraCombo.currentIndexChanged.connect(self.camModChanged)
        self.ui.laserCombo.currentIndexChanged.connect(self.laserDevChanged)
        self.ui.sizeFromCalibrationRadio.toggled.connect(self.updateSpotSizes)
        self.ui.sizeSpin.valueChanged.connect(self.sizeSpinEdited)
        self.ui.minTimeSpin.valueChanged.connect(self.sequenceChanged)
        self.ui.minDistSpin.valueChanged.connect(self.sequenceChanged)
        self.ui.recomputeBtn.clicked.connect(self.recomputeClicked)
        self.ui.loadConfigBtn.clicked.connect(self.loadConfiguration)
        self.ui.previewBtn.toggled.connect(self.previewProgram)
        self.ui.enablePosCtrlCheck.toggled.connect(self.enablePosCtrlToggled)
        self.ui.enableScanProgCheck.toggled.connect(self.enableScanProgToggled)
        self.ui.showLastSpotCheck.toggled.connect(self.showLastSpotToggled)
        self.ui.programPreviewSlider.valueChanged.connect(self.previewRateChanged)
        
        self.dev.sigGlobalSubdeviceChanged.connect(self.opticStateChanged)
        
        self.testTarget = TargetPoint(name="Test", ptSize=100e-6)
        self.testTarget.setPen(Qt.QPen(Qt.QColor(255, 200, 200)))
        self.spotMarker = TargetPoint(name="Last", ptSize=100e-6, movable=False)
        self.spotMarker.setPen(pg.mkPen(color=(255,255,255), width = 2))

        self.spotMarker.hide()
        self.laserDevChanged()  # also updates spot sizes
        self.camModChanged()
        self.updateTDPlot()
            
        #self.ui.simulateShutterCheck.setChecked(False)
        if 'offVoltage' not in self.dev.config: ## we don't have a voltage for virtual shuttering
            self.ui.simulateShutterCheck.setChecked(False)
            self.ui.simulateShutterCheck.setEnabled(False)

        self.daqChanged(self.daqUI.currentState())
        self.daqUI.sigChanged.connect(self.daqChanged)
コード例 #22
0
ファイル: Scan.py プロジェクト: outofculture/acq4
    def displayData(self, fh, plot, pen, evTime=None, eventFilter=None):
        """
        Display data for a single site in a plot--ephys trace, detected events
        Returns all items added to the plot.
        """
        pen = pg.mkPen(pen)

        items = []
        if isinstance(fh, six.string_types):
            fh = self.source()[fh]
        if fh.isDir():
            fh = self.dataModel.getClampFile(fh)

        ## plot all data, incl. events
        data = fh.read()['primary']
        data = fn.besselFilter(data, 4e3)
        pc = plot.plot(data, pen=pen, clear=False)
        items.append(pc)

        ## mark location of event if an event index was given
        if evTime is not None:
            #pos = float(index)/len(data)
            pos = evTime / data.xvals('Time')[-1]
            #print evTime, data.xvals('Time')[-1], pos
            #print index
            arrow = pg.CurveArrow(pc, pos=pos)
            plot.addItem(arrow)
            items.append(arrow)

        events = self.getEvents(fh)['events']

        if eventFilter is not None:
            events = eventFilter(events)

        ## draw ticks over all detected events
        if len(events) > 0:
            if 'fitTime' in events.dtype.names:
                times = events['fitTime']
                ticks = pg.VTickGroup(times, [0.9, 1.0], pen=pen)
                plot.addItem(ticks)
                items.append(ticks)
                #self.mapTicks.append(ticks)

            ## draw event fits
            evPen = pg.mkPen(pen)
            c = evPen.color()
            c.setAlpha(c.alpha() / 2)
            evPen.setColor(c)
            for ev in events:
                time = ev['fitTime']
                try:
                    fitLen = ev['fitDecayTau'] * ev['fitLengthOverDecay']
                except IndexError:
                    fitLen = ev['fitDecayTau'] * 4.
                x = np.linspace(time, time + fitLen, fitLen * 50e3)
                v = [
                    ev['fitAmplitude'], ev['fitTime'], ev['fitRiseTau'],
                    ev['fitDecayTau']
                ]
                y = fn.pspFunc(v, x, risePower=2.0) + data[np.argwhere(
                    data.xvals('Time') > time)[0] - 1]
                evc = plot.plot(x, y, pen=evPen)
                evc.setZValue(pc.zValue() - 100)

        return items
コード例 #23
0
def show(dh=None):
    """
    Display a graphic of the currently selected slice / cell
    """
    
    global v, g, atlas
    if dh is None:
        dh = man.currentFile
    v.clear()
    
    if 'cell' in dh.shortName().lower():
        cd = dh
        sd = cd.parent()
    else:
        sd = dh
        cd = None
    atlas.loadState(sd)
    g = atlas.schematicGraphicsItems()
    v.addItem(g)
    
    if cd is not None:
        ## small image to go over slice schematic
        imgf = cd['morphology.png']
        imgd = pg.colorToAlpha(imgf.read(), np.array([255,255,255]))
        mimg1 = pg.ImageItem(imgd)
        tr = pg.SRTTransform(imgf.info()['userTransform'])
        mimg1.setTransform(tr)
        mimg1.setParentItem(g.sliceGroup)
        g.cellImg1 = mimg1
        
        ## larger image to be displayed above
        cellGroup = pg.ItemGroup()
        g.cellGroup = cellGroup
        mimg2 = pg.ImageItem(imgd)
        mimg2.setParentItem(cellGroup)
        mimg2.setTransform(tr * g.sliceGroup.transform())
        mimg2.scale(1.0 / g.sliceScaleFactor, 1.0 / g.sliceScaleFactor)
        #angle = pg.SRTTransform(g.sliceGroup.transform()).getRotation()
        #mimg2.rotate(angle)
        cellScale = 50.
        cellGroup.scale(cellScale, cellScale)
        g.cellImg2 = mimg2
        
        ## reposition image above slice schematic
        b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())
        b2 = g.sliceClip.mapRectToParent(g.sliceClip.boundingRect())
        bounds = b1 | b2
        cellGroup.setParentItem(g)
        imgBounds = g.mapRectFromItem(mimg2, mimg2.boundingRect())
        pos = pg.Point(bounds.center().x() - imgBounds.center().x(), bounds.top()-imgBounds.bottom()) 
        cellGroup.setPos(pos)
        
        ## add scale bar
        sbLength = 25e-6
        g.cellScale = Qt.QGraphicsLineItem(0.0, 0.0, sbLength, 0.0)
        g.cellScale.setPen(pg.mkPen(color=0.0, width=100e-6/cellScale, cosmetic=False))
        g.cellScale.setParentItem(cellGroup)
        g.cellScale.setZValue(10)
        g.cellScale.text = pg.TextItem(u"25 µm", anchor=(0.5, 1), color=(0,0,0))
        g.cellScale.text.setParentItem(g.cellScale)
        g.cellScale.text.setPos(sbLength*0.5, -50e-6/cellScale)
        corner = mimg2.mapToParent(mimg2.boundingRect()).boundingRect().bottomRight()
        g.cellScale.setPos(corner + pg.Point(-sbLength/2., -sbLength/3.))
        
        cell = dh
        sl = cell.parent()
        day = sl.parent()
        name = day.shortName() + "_" + sl.shortName() + "_" + cell.shortName()
        g.cellName = pg.TextItem(name, color=(0,0,0))
        g.cellName.setParentItem(cellGroup)
        g.cellName.setPos(corner + pg.Point(-sbLength*4,-sbLength/4.))
コード例 #24
0
def showMap(dh=None):
    """
    Display a graphic of an input map for the currently selected cell
    """
    
    global v, g, atlas
    if dh is None:
        dh = man.currentFile
    db = man.getModule('Data Manager').currentDatabase()
    v.clear()
    
    cd = dh
    sd = cd.parent()
    atlas.loadState(sd)
    
    g = atlas.schematicGraphicsItems(contours=False, sliceScale=10, cellDir=cd)
    v.addItem(g)
    
    cellGroup = pg.ItemGroup()
    g.cellGroup = cellGroup
    cellScale = 10.
    cellGroup.scale(cellScale, cellScale)
    cellGroup.setParentItem(g)
    
    g.atlasScale.hide()
    g.arrowGroup.hide()
    
    ## reposition/rescale atlas group
    b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())
    b2 = g.sliceClip.mapRectToParent(g.sliceClip.boundingRect())
    g.atlasGroup.setPos(b2.right()-b1.left()+0.001, b2.top()-b1.top())
    
    b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())    
    bounds = b1 | b2
    
    if cd.exists('morphology.png'):
        ## small image to go over slice schematic
        imgf = cd['morphology.png']
        imgd = pg.colorToAlpha(imgf.read(), np.array([255,255,255]))
        mimg1 = pg.ImageItem(imgd)
        tr = pg.SRTTransform(imgf.info()['userTransform'])
        mimg1.setTransform(tr)
        mimg1.setParentItem(g.sliceGroup)
        mimg1.setZValue(100)
        g.cellImg1 = mimg1
        
        ## larger image to be displayed above
        mimg2 = pg.ImageItem(imgd)
        mimg2.setParentItem(cellGroup)
        mimg2.setTransform(tr * g.sliceGroup.transform())
        mimg2.scale(1.0 / g.sliceScaleFactor, 1.0 / g.sliceScaleFactor)
        #angle = pg.SRTTransform(g.sliceGroup.transform()).getRotation()
        #mimg2.rotate(angle)
        g.cellImg2 = mimg2
        cellGroup.scale(5,5)
        
        ## reposition next to slice schematic
        imgBounds = g.mapRectFromItem(mimg2, mimg2.boundingRect())
        pos = pg.Point(bounds.right()-imgBounds.left(), bounds.bottom()-imgBounds.bottom()) 
        cellGroup.setPos(pos)
    
        ## add scale bar
        sbLength = 50e-6
        g.cellScale = Qt.QGraphicsLineItem(0.0, 0.0, sbLength, 0.0)
        g.cellScale.setPen(pg.mkPen(color=0.0, width=5))
        g.cellScale.setZValue(10)
        g.cellScale.text = pg.TextItem(u"%d µm" % int(sbLength*1e6), anchor=(0.5, 1), color=(0,0,0))
        g.cellScale.text.setParentItem(g.cellScale)
        g.cellScale.text.setPos(sbLength*0.5, -50e-6/cellScale)
        #g.cellScale = pg.ScaleBar(sbLength)
        g.cellScale.setParentItem(cellGroup)
        corner = mimg2.mapToParent(mimg2.boundingRect()).boundingRect().bottomRight()
        g.cellScale.setPos(corner + pg.Point(-sbLength/2., -sbLength/3.))
    pos = pg.SRTTransform(cd.info()['userTransform']).map(pg.Point(0,0))
    size = pg.Point(30e-6, 30e-6)
    g.cellMarker = Qt.QGraphicsEllipseItem(Qt.QRectF(pos-size, pos+size))
    g.cellMarker.setBrush(pg.mkBrush(100,100,255,150))
    g.cellMarker.setPen(pg.mkPen('k', width=0.5))
    g.cellMarker.setParentItem(g.sliceGroup)
    g.cellMarker.setZValue(90)
        
    sites = db.select('map_site_view', ['ProtocolDir', 'HasInput'], where={'CellDir': cd})
    if len(sites) > 0:
        tr = sites[0]['ProtocolDir'].parent().info().get('userTransform', None)
        if tr is None:
            tr = pg.SRTTransform()
        else:
            tr = pg.SRTTransform(tr)
            
        pos = []
        size = sites[0]['ProtocolDir'].info()['Scanner']['spotSize']
        brushes = []
        for site in sites:
            pd = site['ProtocolDir']
            x,y = pd.info()['Scanner']['position']
            p2 = tr.map(pg.Point(x,y))
            pos.append((p2.x(), p2.y()))
            if site['HasInput']:
                brushes.append(pg.mkBrush('w'))
            else:
                brushes.append(pg.mkBrush(None))
        inputMap = pg.ScatterPlotItem(pos=np.array(pos), size=size, brush=brushes, pen=(0,0,0,50), pxMode=False, antialias=True)
        g.sliceGroup.addItem(inputMap)
        g.inputMap = inputMap
        inputMap.setZValue(50)
    
    
    cell = dh
    sl = cell.parent()
    day = sl.parent()
    name = day.shortName() + "_" + sl.shortName() + "_" + cell.shortName()
    rec = db.select('DirTable_Cell', '*', where={'Dir': cd})[0]
    
    name += "\nType: " + str(rec['CellType']) + "   Temp: " + str(rec['Temperature']) + "   Internal: " + str(rec['Internal']) + "   Age:" + str(rec['Age']) + "   Raccess: " + str(rec['AccessResistance'])
    name += "\nDirect Area: %s>0pA %s>20pA %s>100pA" % (str(rec['DirectAreaGt0']), str(rec['DirectAreaGt20']), str(rec['DirectAreaGt100']))
    name += "   Direct n spikes: " + str(rec['DirectNSpikes'])
    name += "\nSpont Ex Decay: %s   Spont In Decay: %s" % (str(rec['SpontExDecay1']), str(rec['SpontInDecay']))
    name += "\nExcitatory input" if (rec['EvokedExDecay'] is not None or rec['EvokedExAmp'] is not None) else ""
    print(rec)
    #name += '\nDirect Slow Decay: %s %s' % (str(rec['DirectAreaGT0']), str(rec['DirectAreaGT0']))
    
    
    
    g.cellName = pg.TextItem(name, color=(0,0,0))
    g.cellName.setParentItem(g)
    g.cellName.setPos(0, bounds.bottom())
コード例 #25
0
ファイル: TaskGui.py プロジェクト: ablot/acq4
    def __init__(self, dev, taskRunner):
        TaskGui.__init__(self, dev, taskRunner)
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        dm = getManager()
        self.targets = None
        self.items = {}
        self.haveCalibration = True   ## whether there is a calibration for the current combination of laser/optics
        self.currentOpticState = None
        self.currentCamMod = None
        self.programCtrls = []
        self.displaySize = {}  ## maps (laser,opticState) : display size
                               ## since this setting is remembered for each objective.
        
        ## Populate module/device lists, auto-select based on device defaults 
        self.defCam = None
        if 'defaultCamera' in self.dev.config:
            self.defCam = self.dev.config['defaultCamera']
        defLaser = None
        if 'defaultLaser' in self.dev.config:
            defLaser = self.dev.config['defaultLaser']

        self.ui.cameraCombo.setTypes(['cameraModule'])
        self.ui.laserCombo.setTypes(['laser'])
        
        self.positionCtrlGroup = PositionCtrlGroup()
        self.positionCtrlGroup.sigAddNewRequested.connect(self.addPositionCtrl)
        self.ui.itemTree.setParameters(self.positionCtrlGroup, showTop=False)
        self.positionCtrlGroup.sigChildRemoved.connect(self.positionCtrlRemoved)
        
        self.programCtrlGroup = ProgramCtrlGroup()
        self.programCtrlGroup.sigAddNewRequested.connect(self.addProgramCtrl)
        self.ui.programTree.setParameters(self.programCtrlGroup, showTop=False)
        self.programCtrlGroup.sigChildRemoved.connect(self.programCtrlRemoved)

        ## Set up SpinBoxes
        self.ui.minTimeSpin.setOpts(dec=True, step=1, minStep=1e-3, siPrefix=True, suffix='s', bounds=[0, 50])
        self.ui.minDistSpin.setOpts(dec=True, step=1, minStep=1e-6, siPrefix=True, suffix='m', bounds=[0, 10e-3])
        self.ui.sizeSpin.setOpts(dec=True, step=1, minStep=1e-6, siPrefix=True, suffix='m', bounds=[1e-9, 1e-3])
        ## Create state group for saving/restoring state
        self.stateGroup = pg.WidgetGroup([
            (self.ui.cameraCombo,),
            (self.ui.laserCombo,),
            (self.ui.minTimeSpin, 'minTime'),
            (self.ui.minDistSpin, 'minDist'),
            (self.ui.simulateShutterCheck, 'simulateShutter'),
            (self.ui.sizeSpin, 'spotSize'),
        ])
        self.stateGroup.setState({'minTime': 10, 'minDist': 500e-6, 'sizeSpin':100e-6})
        self.tdPlot = self.ui.tdPlotWidget.plotItem
        self.tdPlot.setLabel('bottom', text="Distance", units='m')
        self.tdPlot.setLabel('left', text="Wait time", units='s')

        ## Note we use lambda functions for all these clicks to strip out the arg sent with the signal
        
        self.ui.hideCheck.toggled.connect(self.showInterface)
        self.ui.hideMarkerBtn.clicked.connect(self.hideSpotMarker)
        self.ui.cameraCombo.currentIndexChanged.connect(self.camModChanged)
        self.ui.laserCombo.currentIndexChanged.connect(self.laserDevChanged)
        self.ui.sizeFromCalibrationRadio.toggled.connect(self.updateSpotSizes)
        self.ui.sizeSpin.valueChanged.connect(self.sizeSpinEdited)
        self.ui.minTimeSpin.valueChanged.connect(self.sequenceChanged)
        self.ui.minDistSpin.valueChanged.connect(self.sequenceChanged)
        self.ui.recomputeBtn.clicked.connect(self.recomputeClicked)
        self.ui.loadConfigBtn.clicked.connect(self.loadConfiguration)
        
        self.dev.sigGlobalSubdeviceChanged.connect(self.opticStateChanged)
        
        self.testTarget = TargetPoint(name="Test", ptSize=100e-6)
        self.testTarget.setPen(QtGui.QPen(QtGui.QColor(255, 200, 200)))
        self.spotMarker = TargetPoint(name="Last", ptSize=100e-6, movable=False)
        self.spotMarker.setPen(pg.mkPen(color=(255,255,255), width = 2))

        self.spotMarker.hide()
        self.updateSpotSizes()

        self.camModChanged()
        self.updateTDPlot()
        
            
        #self.ui.simulateShutterCheck.setChecked(False)
        if 'offVoltage' not in self.dev.config: ## we don't have a voltage for virtual shuttering
            self.ui.simulateShutterCheck.setChecked(False)
            self.ui.simulateShutterCheck.setEnabled(False)
コード例 #26
0
ファイル: line.py プロジェクト: outofculture/acq4
 def recolor(self):
     for i, s in enumerate(self.segments):
         if i % 2 == 0:
             s.setPen(self.pen)
         else:
             s.setPen(pg.mkPen([75, 200, 75]))
コード例 #27
0
ファイル: eventExplorer.py プロジェクト: outofculture/acq4
    ## 3D atlas
    import acq4.analysis.atlas.CochlearNucleus as CN
    atlas = CN.CNAtlasDisplayWidget()
    atlas.showLabel('DCN')
    atlas.showLabel('AVCN')
    atlas.showLabel('PVCN')
    tab.addTab(atlas, 'Atlas')

    atlasPoints = gl.GLScatterPlotItem()
    atlas.addItem(atlasPoints)

    win.show()
    win.resize(1000, 800)

    sp1 = pw1.scatterPlot([],
                          pen=pg.mkPen(None),
                          brush=(200, 200, 255, 70),
                          identical=True,
                          size=8)
    sp2 = pw1.scatterPlot([],
                          pen=pg.mkPen(None),
                          brush=(255, 200, 200, 70),
                          identical=True,
                          size=8)
    sp3 = pw1.scatterPlot([],
                          pen=pg.mkPen(None),
                          brush=(100, 255, 100, 70),
                          identical=True,
                          size=8)
    sp4 = pw1.scatterPlot([], pen=pg.mkPen(None), size=8)
コード例 #28
0
ファイル: CortexROI.py プロジェクト: ablot/acq4
    def __init__(self, pos, state=None):
        ROI.PolyLineROI.__init__(self, [[0,0], [2,0], [2,1], [0,1]], pos=pos, closed=True, pen=pg.mkPen(50,50, 255, 200))
        
        ## don't let the user add handles to the sides, only to the top and bottom
        self.segments[0].setAcceptedMouseButtons(QtCore.Qt.NoButton)
        #self.segments[1].setAcceptedMouseButtons(QtCore.Qt.NoButton) ## there was a change in PolylineROI that affected the order of segments, so now 0 and 2 are the sides instead of 1 and 3 (2013.12.12)
        self.segments[2].setAcceptedMouseButtons(QtCore.Qt.NoButton)
        #self.segments[3].setAcceptedMouseButtons(QtCore.Qt.NoButton)

        if state is not None:
            self.setState(state)
コード例 #29
0
ファイル: eventExplorer.py プロジェクト: ablot/acq4
    ## 3D atlas
    import acq4.analysis.atlas.CochlearNucleus as CN
    atlas = CN.CNAtlasDisplayWidget()
    atlas.showLabel('DCN')
    atlas.showLabel('AVCN')
    atlas.showLabel('PVCN')
    tab.addTab(atlas, 'Atlas')
    
    atlasPoints = gl.GLScatterPlotItem()
    atlas.addItem(atlasPoints)
    
    win.show()
    win.resize(1000,800)

    sp1 = pw1.scatterPlot([], pen=pg.mkPen(None), brush=(200,200,255,70), identical=True, size=8)
    sp2 = pw1.scatterPlot([], pen=pg.mkPen(None), brush=(255,200,200,70), identical=True, size=8)
    sp3 = pw1.scatterPlot([], pen=pg.mkPen(None), brush=(100,255,100,70), identical=True, size=8)
    sp4 = pw1.scatterPlot([], pen=pg.mkPen(None), size=8)

    


    print "Reading cell list..."
    
    #import os, pickle
    #md = os.path.abspath(os.path.split(__file__)[0])
    #cacheFile = os.path.join(md, 'eventCache.p')
    #if os.path.isfile(cacheFile):
        #print "Read from cache..."
        #ev = pickle.load(open(cacheFile, 'r'))
コード例 #30
0
 def setPen(self, pen):
     pen = pg.mkPen(pen)
     self.pen = pen
     for t in self.times:
         t.setPen(pen)
コード例 #31
0
ファイル: sliceView.py プロジェクト: ablot/acq4
def show(dh=None):
    """
    Display a graphic of the currently selected slice / cell
    """
    
    global v, g, atlas
    if dh is None:
        dh = man.currentFile
    v.clear()
    
    if 'cell' in dh.shortName().lower():
        cd = dh
        sd = cd.parent()
    else:
        sd = dh
        cd = None
    atlas.loadState(sd)
    g = atlas.schematicGraphicsItems()
    v.addItem(g)
    
    if cd is not None:
        ## small image to go over slice schematic
        imgf = cd['morphology.png']
        imgd = pg.colorToAlpha(imgf.read(), np.array([255,255,255]))
        mimg1 = pg.ImageItem(imgd)
        tr = pg.SRTTransform(imgf.info()['userTransform'])
        mimg1.setTransform(tr)
        mimg1.setParentItem(g.sliceGroup)
        g.cellImg1 = mimg1
        
        ## larger image to be displayed above
        cellGroup = pg.ItemGroup()
        g.cellGroup = cellGroup
        mimg2 = pg.ImageItem(imgd)
        mimg2.setParentItem(cellGroup)
        mimg2.setTransform(tr * g.sliceGroup.transform())
        mimg2.scale(1.0 / g.sliceScaleFactor, 1.0 / g.sliceScaleFactor)
        #angle = pg.SRTTransform(g.sliceGroup.transform()).getRotation()
        #mimg2.rotate(angle)
        cellScale = 50.
        cellGroup.scale(cellScale, cellScale)
        g.cellImg2 = mimg2
        
        ## reposition image above slice schematic
        b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())
        b2 = g.sliceClip.mapRectToParent(g.sliceClip.boundingRect())
        bounds = b1 | b2
        cellGroup.setParentItem(g)
        imgBounds = g.mapRectFromItem(mimg2, mimg2.boundingRect())
        pos = pg.Point(bounds.center().x() - imgBounds.center().x(), bounds.top()-imgBounds.bottom()) 
        cellGroup.setPos(pos)
        
        ## add scale bar
        sbLength = 25e-6
        g.cellScale = pg.QtGui.QGraphicsLineItem(0.0, 0.0, sbLength, 0.0)
        g.cellScale.setPen(pg.mkPen(color=0.0, width=100e-6/cellScale, cosmetic=False))
        g.cellScale.setParentItem(cellGroup)
        g.cellScale.setZValue(10)
        g.cellScale.text = pg.TextItem(u"25 µm", anchor=(0.5, 1), color=(0,0,0))
        g.cellScale.text.setParentItem(g.cellScale)
        g.cellScale.text.setPos(sbLength*0.5, -50e-6/cellScale)
        corner = mimg2.mapToParent(mimg2.boundingRect()).boundingRect().bottomRight()
        g.cellScale.setPos(corner + pg.Point(-sbLength/2., -sbLength/3.))
        
        cell = dh
        sl = cell.parent()
        day = sl.parent()
        name = day.shortName() + "_" + sl.shortName() + "_" + cell.shortName()
        g.cellName = pg.TextItem(name, color=(0,0,0))
        g.cellName.setParentItem(cellGroup)
        g.cellName.setPos(corner + pg.Point(-sbLength*4,-sbLength/4.))
コード例 #32
0
ファイル: sliceView.py プロジェクト: ablot/acq4
def showMap(dh=None):
    """
    Display a graphic of an input map for the currently selected cell
    """
    
    global v, g, atlas
    if dh is None:
        dh = man.currentFile
    db = man.getModule('Data Manager').currentDatabase()
    v.clear()
    
    cd = dh
    sd = cd.parent()
    atlas.loadState(sd)
    
    g = atlas.schematicGraphicsItems(contours=False, sliceScale=10, cellDir=cd)
    v.addItem(g)
    
    cellGroup = pg.ItemGroup()
    g.cellGroup = cellGroup
    cellScale = 10.
    cellGroup.scale(cellScale, cellScale)
    cellGroup.setParentItem(g)
    
    g.atlasScale.hide()
    g.arrowGroup.hide()
    
    ## reposition/rescale atlas group
    b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())
    b2 = g.sliceClip.mapRectToParent(g.sliceClip.boundingRect())
    g.atlasGroup.setPos(b2.right()-b1.left()+0.001, b2.top()-b1.top())
    
    b1 = g.atlasGroup.mapRectToParent(g.atlasGroup.childrenBoundingRect())    
    bounds = b1 | b2
    
    if cd.exists('morphology.png'):
        ## small image to go over slice schematic
        imgf = cd['morphology.png']
        imgd = pg.colorToAlpha(imgf.read(), np.array([255,255,255]))
        mimg1 = pg.ImageItem(imgd)
        tr = pg.SRTTransform(imgf.info()['userTransform'])
        mimg1.setTransform(tr)
        mimg1.setParentItem(g.sliceGroup)
        mimg1.setZValue(100)
        g.cellImg1 = mimg1
        
        ## larger image to be displayed above
        mimg2 = pg.ImageItem(imgd)
        mimg2.setParentItem(cellGroup)
        mimg2.setTransform(tr * g.sliceGroup.transform())
        mimg2.scale(1.0 / g.sliceScaleFactor, 1.0 / g.sliceScaleFactor)
        #angle = pg.SRTTransform(g.sliceGroup.transform()).getRotation()
        #mimg2.rotate(angle)
        g.cellImg2 = mimg2
        cellGroup.scale(5,5)
        
        ## reposition next to slice schematic
        imgBounds = g.mapRectFromItem(mimg2, mimg2.boundingRect())
        pos = pg.Point(bounds.right()-imgBounds.left(), bounds.bottom()-imgBounds.bottom()) 
        cellGroup.setPos(pos)
    
        ## add scale bar
        sbLength = 50e-6
        g.cellScale = pg.QtGui.QGraphicsLineItem(0.0, 0.0, sbLength, 0.0)
        g.cellScale.setPen(pg.mkPen(color=0.0, width=5))
        g.cellScale.setZValue(10)
        g.cellScale.text = pg.TextItem(u"%d µm" % int(sbLength*1e6), anchor=(0.5, 1), color=(0,0,0))
        g.cellScale.text.setParentItem(g.cellScale)
        g.cellScale.text.setPos(sbLength*0.5, -50e-6/cellScale)
        #g.cellScale = pg.ScaleBar(sbLength)
        g.cellScale.setParentItem(cellGroup)
        corner = mimg2.mapToParent(mimg2.boundingRect()).boundingRect().bottomRight()
        g.cellScale.setPos(corner + pg.Point(-sbLength/2., -sbLength/3.))
    pos = pg.SRTTransform(cd.info()['userTransform']).map(pg.Point(0,0))
    size = pg.Point(30e-6, 30e-6)
    g.cellMarker = pg.QtGui.QGraphicsEllipseItem(pg.QtCore.QRectF(pos-size, pos+size))
    g.cellMarker.setBrush(pg.mkBrush(100,100,255,150))
    g.cellMarker.setPen(pg.mkPen('k', width=0.5))
    g.cellMarker.setParentItem(g.sliceGroup)
    g.cellMarker.setZValue(90)
        
    sites = db.select('map_site_view', ['ProtocolDir', 'HasInput'], where={'CellDir': cd})
    if len(sites) > 0:
        tr = sites[0]['ProtocolDir'].parent().info().get('userTransform', None)
        if tr is None:
            tr = pg.SRTTransform()
        else:
            tr = pg.SRTTransform(tr)
            
        pos = []
        size = sites[0]['ProtocolDir'].info()['Scanner']['spotSize']
        brushes = []
        for site in sites:
            pd = site['ProtocolDir']
            x,y = pd.info()['Scanner']['position']
            p2 = tr.map(pg.Point(x,y))
            pos.append((p2.x(), p2.y()))
            if site['HasInput']:
                brushes.append(pg.mkBrush('w'))
            else:
                brushes.append(pg.mkBrush(None))
        inputMap = pg.ScatterPlotItem(pos=np.array(pos), size=size, brush=brushes, pen=(0,0,0,50), pxMode=False, antialias=True)
        g.sliceGroup.addItem(inputMap)
        g.inputMap = inputMap
        inputMap.setZValue(50)
    
    
    cell = dh
    sl = cell.parent()
    day = sl.parent()
    name = day.shortName() + "_" + sl.shortName() + "_" + cell.shortName()
    rec = db.select('DirTable_Cell', '*', where={'Dir': cd})[0]
    
    name += "\nType: " + str(rec['CellType']) + "   Temp: " + str(rec['Temperature']) + "   Internal: " + str(rec['Internal']) + "   Age:" + str(rec['Age']) + "   Raccess: " + str(rec['AccessResistance'])
    name += "\nDirect Area: %s>0pA %s>20pA %s>100pA" % (str(rec['DirectAreaGt0']), str(rec['DirectAreaGt20']), str(rec['DirectAreaGt100']))
    name += "   Direct n spikes: " + str(rec['DirectNSpikes'])
    name += "\nSpont Ex Decay: %s   Spont In Decay: %s" % (str(rec['SpontExDecay1']), str(rec['SpontInDecay']))
    name += "\nExcitatory input" if (rec['EvokedExDecay'] is not None or rec['EvokedExAmp'] is not None) else ""
    print rec
    #name += '\nDirect Slow Decay: %s %s' % (str(rec['DirectAreaGT0']), str(rec['DirectAreaGT0']))
    
    
    
    g.cellName = pg.TextItem(name, color=(0,0,0))
    g.cellName.setParentItem(g)
    g.cellName.setPos(0, bounds.bottom())
コード例 #33
0
ファイル: TaskGui.py プロジェクト: ablot/acq4
 def recolor(self):
     for i, s in enumerate(self.segments):
         if i % 2 == 0:
             s.setPen(self.pen)
         else:
             s.setPen(pg.mkPen([75, 200, 75]))