Ejemplo n.º 1
0
class LoggedStepperMotor(CounterStepperMotor):
    def __init__(self,
                 counter_channel,
                 direction_channel,
                 log_file=None,
                 enable_channel=None,
                 backlash=0,
                 tasks=None):
        import os.path
        if log_file is None:
            logName = str(counter_channel).replace('/', '-') + '.txt'
        else:
            logName = log_file
        self.logName = os.path.join(SMLOGSPATH, logName)
        self._openLog()
        try:
            last_date, last_position, last_direction = self._getLastPosition()
        except TypeError:
            print 'error with log file! reverting to 0 & forwards'
            last_date, last_position, last_direction = ('never', 0, 'FORWARDS')
        last_direction = {
            'FORWARDS': DigitalLineStepperMotor.FORWARDS,
            'BACKWARDS': DigitalLineStepperMotor.BACKWARDS
        }[last_direction]

        CounterStepperMotor.__init__(self,
                                     counter_channel,
                                     direction_channel,
                                     enable_channel=enable_channel,
                                     initial_position=int(last_position),
                                     backlash=backlash,
                                     direction=last_direction,
                                     tasks=tasks)

    def _openLog(self):
        self.log_file = LogFile(self.logName)

    def _closeLog(self):
        self.log_file.close()

    def toggleStatus(self):
        if self._getEnableStatus() == self.ENABLED:
            self.updateLog()
            self._closeLog()
            self.disable()
        elif self._getEnableStatus() == self.DISABLED:
            self._openLog()
            self.enable()

    def _getLastPosition(self):
        return self.log_file.readLastLine()

    def updateLog(self):
        currPos = self.getPosition()
        currDir = self.getDirection()
        self.log_file.update((currPos, currDir))

    def destroy(self):
        self._closeLog()
        EnabledStepperMotor.destroy(self)
Ejemplo n.º 2
0
def onReady():
    vm_prot = yield getProtocol(VOLTMETER_SERVER)
    sm_prot = yield getProtocol(STEPPER_MOTOR_SERVER)
    dg_prot = yield getProtocol(DELAY_GENERATOR_SERVER)

    vm = VoltMeterClient(vm_prot)
    sm = StepperMotorClient(sm_prot,POL)
    dg = DelayGeneratorClient(dg_prot)

    delays = yield dg.getDelays()
    pumpTime = delays[MAV_PUMP_QSW]
    
    times = np.arange(TIME_START+pumpTime,TIME_STOP+pumpTime+TIME_STEP,TIME_STEP)

    angles = np.arange(ANGLE_START,ANGLE_STOP+ANGLE_STEP,ANGLE_STEP)
    
    channels = yield vm.getChannels()
    channel = yield selectFromList(channels,'pick the mcp channel')
    
    trans = yield selectFromList(['Q3','S3','Q1'],'pick the transition you are at')
    bsang = yield selectFromList(['020','110'],'pick the angle of the beam splitter')
    
    for i in range(REPEAT):
        for angle in np.concatenate((angles,angles[::-1])):
            yield sm.setPosition(int(degrees_to_steps(angle)))
            angleStr = str(angle).zfill(3)
            relPath, fileName = filenameGen(path.join(trans,'TimeOfFlight','BS'+str(bsang),'HWP'+angleStr))
            absPath = path.join(POOHDATAPATH,relPath)
            checkPath(absPath)
            logName = path.join(absPath,fileName+'.tsv')
            thisLog = LogFile(logName)
            for time in times[::-1]:
                yield dg.setPartnerDelay(MAV_PROBE_QSW, int(time))
                voltage, std = yield vm.getNVoltages(channel,SHOTS)
                stdom = std/np.sqrt(SHOTS)
                print (angle,time-pumpTime,voltage,stdom)
                thisLog.update([time,voltage,stdom])
            thisLog.close()
            print BELL
            if WAIT_FOR_TUNE:
                pause(None,None)    
    reactor.stop()
Ejemplo n.º 3
0
def onReady():
    vm_prot = yield getProtocol(VOLTMETER_SERVER)
    sm_prot = yield getProtocol(STEPPER_MOTOR_SERVER)

    vm = VoltMeterClient(vm_prot)
    sm = StepperMotorClient(sm_prot,POL)

    channels = yield vm.getChannels()
    channel = yield selectFromList(channels,'pick the mcp channel')
    
    trans = yield selectFromList(['Q3','S3','Q1'],'pick the transition you are at')
    
    bsang = yield selectFromList(['020','110'],'pick the angle of the beam splitter')
    
    # #suffix = yield selectFromList(['pump','unpump'],'are you pumping?')
    suffix = 'mBeamOff_diffZeroed'
    
    numPoints = (ANGLE_STOP-ANGLE_START+1)/ANGLE_STEP
    totalAcqTime = SWEEPS*2*(SHOTS/10.)*numPoints
    totalStepTime = ((ANGLE_STEP*SLOPE)/500.)*numPoints
    print 'ETA is: '+str((totalAcqTime + totalStepTime)/60.)+' minutes.'

    for sweep in range(SWEEPS):
        for direction in (FORWARDS,BACKWARDS):
            relPath, fileName = filenameGen(trans)
            absPath = path.join(POOHDATAPATH,relPath)
            checkPath(absPath)
            logName = path.join(absPath,fileName+'_pol_sweep_'+bsang+'_'+suffix+'.tsv')
            thisLog = LogFile(logName)
            for angle in {
                    FORWARDS:forwards,
                    BACKWARDS:backwards
                    }[direction]:
                yield sm.setPosition(int(degrees_to_steps(angle)))
                voltage, std = yield vm.getNVoltages(channel,SHOTS)
                stdom = std/np.sqrt(SHOTS)
                print (sweep,angle,voltage, stdom)
                thisLog.update([angle,voltage,stdom])
            thisLog.close()
            
    reactor.stop()    
Ejemplo n.º 4
0
 def onRecordStartRequested():
     # build a list of selected channels, record only those, set text color to red
     for channel in channels:
         tile = tiles[channel]
         if tile.checkState() is QtCore.Qt.CheckState.Checked:
             recording.append(channel)
             tile.setForeground(
                 QtGui.QBrush(
                     QtGui.QColor('red')
                 )
             )
     
     # initialize logfile in today's folder / voltmeter / start time
     relPath, fileName = filenameGen(self.MEASUREMENT_TYPE)
     absPath = os.path.join(POOHDATAPATH,relPath)
     checkPath(absPath)
     logName = os.path.join(absPath,fileName+'.txt')
     self.LogFile = LogFile(logName)
     headerLine = []
     for channel in recording:
         headerLine.append(tiles[channel].text().replace('\t','_'))
     self.LogFile.update(headerLine)
     recordToggle.toggle()
Ejemplo n.º 5
0
 def _openLog(self):
     self.log_file = LogFile(self.logName)
Ejemplo n.º 6
0
class LoggedStepperMotor(CounterStepperMotor):
    def __init__(
        self,
        counter_channel,
        direction_channel,
        log_file=None,
        enable_channel=None,
        backlash=0,
        tasks=None
    ):
        import os.path
        if log_file is None:
            logName = str(counter_channel).replace('/','-')+'.txt'
        else:
            logName = log_file
        self.logName = os.path.join(SMLOGSPATH,logName)
        self._openLog()
        try:
            last_date, last_position, last_direction = self._getLastPosition()
        except TypeError:
            print 'error with log file! reverting to 0 & forwards'
            last_date, last_position, last_direction = ('never',0,'FORWARDS')
        last_direction = {'FORWARDS':DigitalLineStepperMotor.FORWARDS,'BACKWARDS':DigitalLineStepperMotor.BACKWARDS}[last_direction]
        
        CounterStepperMotor.__init__(
            self,
            counter_channel,
            direction_channel,
            enable_channel=enable_channel,
            initial_position=int(last_position),
            backlash=backlash,
            direction=last_direction,
            tasks=tasks
        )
    
    def _openLog(self):
        self.log_file = LogFile(self.logName)
    
    def _closeLog(self):
        self.log_file.close()
    
    def toggleStatus(self):
        if self._getEnableStatus() == self.ENABLED: 
            self.updateLog()
            self._closeLog()
            self.disable()
        elif self._getEnableStatus() == self.DISABLED: 
            self._openLog()
            self.enable()
    
    def _getLastPosition(self):
        return self.log_file.readLastLine()
   
    def updateLog(self):
        currPos = self.getPosition()
        currDir = self.getDirection()
        self.log_file.update((currPos,currDir))
        
    def destroy(self):
        self._closeLog()
        EnabledStepperMotor.destroy(self)
Ejemplo n.º 7
0
 def _openLog(self):
     self.log_file = LogFile(self.logName)
Ejemplo n.º 8
0
class VoltMeterWidget(QtGui.QWidget):    
    ID_ROLE = 999
    HISTORY = 200
    MEASUREMENT_TYPE = 'voltmeter'
    newBufferVal = False 
        
    @staticmethod
    def vrngk2v(k):
        vrngKeys, vrngVals = zip(*VM.VOLTAGE_RANGES)
        return vrngVals[vrngKeys.index(k)]
        
    def __init__(self,protocol):
        @inlineCallbacks
        def init():
            # to change displayed values of channel tiles
            @inlineCallbacks
            def setText(channel):
                description = yield protocol.sendCommand(
                    'get-channel-parameter',
                    channel,
                    VM.DESCRIPTION
                )
                voltageRange = yield protocol.sendCommand(
                    'get-channel-parameter',
                    channel,
                    VM.VOLTAGE_RANGE
                )
                voltageRange = self.vrngk2v(voltageRange)
                
                decimalPlaces = int(-1*log10(voltageRange)) + 1
                formatString = '%.' + str(decimalPlaces if decimalPlaces > 0 else 0) + 'f'
                tiles[channel].setText(
                    '%s\t%s\t%s V' % (
                        description,
                        channel,
                        (
                            formatString
                        ) % voltageRange
                    )
                )
            
            # to bring up channel edit dialogue
            def rightClicked(listWidget,p):
                item = listWidget.itemAt(p)
                if item is None: return
                channel = item.data(self.ID_ROLE)
                editDialog = ChannelEditDialog(protocol,channel,colors[channel],self)
                editDialog.colorChanged.connect(partial(colorChanged,channel))
                editDialog.show()
            
            # to update a channel's color
            def colorChanged(channel,color):
                colors[channel] = color
                tiles[channel].setBackground(color)
                plots[channel].setPen(
                    pg.mkPen(
                        color,
                        width=2
                    )
                )
            
            # the main execution loop
            @inlineCallbacks
            def loop():
                # get latest values
                voltages = yield protocol.sendCommand('get-voltages')
                for channel, voltage in voltages.items():
                    # extend the size of arrays if user asks for more values to be stored
                    if self.newBufferVal == True: onBufferUpdate()
                    
                    # populate arrays from historical values
                    xData, yData = data[channel]
                    
                    # pop oldest voltage
                    yData = np.delete(yData,0)
                                #scale = yield protocol.sendCommand(
                                #    'get-channel-parameter',
                                #    channel,
                                #    VM.VOLTAGE_RANGE
                                #)
                                #scale = self.vrngk2v(scale)
                    # add newest voltage
                    yData = np.append(yData,np.asarray(voltage))
                    
                    # plot all voltages in range
                    plots[channel].setData(
                        xData,
                        yData
                    )
                    
                    # set the historical values to these values
                    data[channel] = (xData, yData)
                
                # log values, if requested
                if recordToggle.isToggled():
                    nextLine = []
                    for channel in recording:
                        nextLine.append(voltages[channel])
                    self.LogFile.update(nextLine)
                
                # update selected list
                for channel in channels:
                    tile = tiles[channel]
                    if tile.checkState() is QtCore.Qt.CheckState.Checked:
                        if channel not in checked:
                            checked.append(channel)
                            plotWidget.addItem(
                                plots[channel]
                            )
                    elif channel in checked:
                        checked.remove(channel)
                        plotWidget.removeItem(
                            plots[channel]
                        )
                
                # wait for server's callback rate (nom. 10Hz), iterate
                callbackRate = yield protocol.sendCommand('get-callback-rate')
                yield sleep(1.0 / callbackRate)
                loop()

            # define overall layout: graph to left of control panel
            QtGui.QWidget.__init__(self)
            self.setLayout(QtGui.QHBoxLayout())
            
            # define plot
            plotWidget = pg.PlotWidget()
            self.layout().addWidget(plotWidget,1)
            
            # define controls panel
            controlsLayout = QtGui.QVBoxLayout()
            self.layout().addLayout(controlsLayout)

            # define the list for variable tiles to go onto
            listWidget = QtGui.QListWidget()
            listWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
            listWidget.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
            listWidget.customContextMenuRequested.connect(
                partial(
                    rightClicked,
                    listWidget
                )
            )
            controlsLayout.addWidget(listWidget)
           
            # iterate through channels on server and populate dictionaries for data, colors, and plots
            channels = yield protocol.sendCommand('get-channels')
            channels = sorted(channels,key = lambda channel: int(re.search('\d+$',channel).group()))
            data =  {}
            colors =  {}
            plots =  {}
            tiles = {}
            for index, channel in enumerate(channels):
                data[channel] = (np.arange(self.HISTORY), np.zeros(self.HISTORY))
                colors[channel] = QtGui.QColor.fromHsv(
                    int(255*float(index)/len(channels)),
                    255,
                    255
                )
                plots[channel] = pg.PlotDataItem(
                    data[channel][0],
                    data[channel][1],
                    name=channel,
                    pen=pg.mkPen(colors[channel], width=2)
                )
                description = yield protocol.sendCommand(
                    'get-channel-parameter',
                    channel,
                    VM.DESCRIPTION
                )
                listWidgetTile = QtGui.QListWidgetItem()                
                listWidgetTile.setData(self.ID_ROLE,channel)
                listWidgetTile.setBackground(QtGui.QBrush(colors[channel]))
                listWidgetTile.setCheckState(QtCore.Qt.CheckState.Unchecked)
                listWidget.addItem(listWidgetTile)
                tiles[channel] = listWidgetTile
                setText(channel)
            
            # when a channel is updated, update its associated tile
            def onChannelParameterChanged(channel,parameter,value):
                setText(channel)
            protocol.messageSubscribe(
                'channel-parameter-changed',
                partial(
                    apply,
                    onChannelParameterChanged
                )                
            )
            
            # set up buffer function and spinbox
            def onBufferUpdate():
                oldBufferSize = data[channels[0]][0].size
                newBufferSize = bufferSpin.value()
                change = newBufferSize - oldBufferSize
                
                if change > 0:
                    backendToAdd = np.zeros(change)
                    for index, channel in enumerate(channels):
                        data[channel] = (
                            np.arange(newBufferSize),
                            np.hstack((backendToAdd,data[channel][1]))
                        )
                
                if change < 0:
                    for index, channel in enumerate(channels):
                        data[channel] = (
                            np.arange(newBufferSize),
                            np.delete(data[channel][1],np.arange(abs(change)))
                        )
                
                self.newBufferVal = False
            
            def newBufferToggle():
                self.newBufferVal = True
            
            bufferSpin = QtGui.QSpinBox()
            bufferSpin.setRange(1,100000)
            bufferSpin.setValue(self.HISTORY)
            controlsLayout.addWidget(LabelWidget('buffer',bufferSpin))
            bufferSpin.editingFinished.connect(newBufferToggle)
            
            # set up recording functions and buttons
            checked = []
            recording = []            
            recordToggle = ToggleObject()
            def onRecordStartRequested():
                # build a list of selected channels, record only those, set text color to red
                for channel in channels:
                    tile = tiles[channel]
                    if tile.checkState() is QtCore.Qt.CheckState.Checked:
                        recording.append(channel)
                        tile.setForeground(
                            QtGui.QBrush(
                                QtGui.QColor('red')
                            )
                        )
                
                # initialize logfile in today's folder / voltmeter / start time
                relPath, fileName = filenameGen(self.MEASUREMENT_TYPE)
                absPath = os.path.join(POOHDATAPATH,relPath)
                checkPath(absPath)
                logName = os.path.join(absPath,fileName+'.txt')
                self.LogFile = LogFile(logName)
                headerLine = []
                for channel in recording:
                    headerLine.append(tiles[channel].text().replace('\t','_'))
                self.LogFile.update(headerLine)
                recordToggle.toggle()
            recordToggle.activationRequested.connect(onRecordStartRequested)
            
            def onRecordStopRequested():
                while recording:
                    tiles[recording.pop()].setForeground(
                        QtGui.QBrush(
                            QtGui.QColor('black')
                        )
                    )
                recordToggle.toggle()
                self.LogFile.close()
            recordToggle.deactivationRequested.connect(onRecordStopRequested)
            
            # add record & stop buttons to layout
            controlsLayout.addWidget(ToggleWidget(recordToggle,('record','stop')))
            
            loop()   
        init()
        
    def closeEvent(self, event):
        event.accept()
        quit()