class IgorThread(QtCore.QThread): _newRequest = QtCore.Signal(object) def __init__(self, useZMQ=False): QtCore.QThread.__init__(self) self.moveToThread(self) if useZMQ: self.igor = ZMQIgorBridge() else: self.igor = IgorBridge() self._newRequest.connect(self._processRequest) self.start() atexit.register(self.quit) def __call__(self, *args, **kwds): return self._sendRequest('__call__', args, kwds) def getWave(self, *args, **kwds): return self._sendRequest('getWave', args, kwds) def getVariable(self, *args, **kwds): return self._sendRequest('getVariable', args, kwds) def _sendRequest(self, req, args, kwds): if isinstance(self.igor, ZMQIgorBridge): return getattr(self.igor, req)(*args) else: fut = concurrent.futures.Future() self._newRequest.emit((fut, req, args, kwds)) return fut def _processRequest(self, req): fut, method, args, kwds = req try: result = getattr(self.igor, method)(*args, **kwds) fut.set_result(result) except Exception as exc: fut.set_exception(exc) def run(self): pythoncom.CoInitialize() QtCore.QThread.run(self)
class ScanProgramCtrlGroup(pTypes.GroupParameter): """ Parameter tree used for generating ScanProgram """ sigAddNewRequested = QtCore.Signal(object, object) def __init__(self): opts = { 'name': 'Program Controls', 'type': 'group', 'addText': "Add Control..", 'addList': COMPONENTS.keys(), 'autoIncrementName': True, } pTypes.GroupParameter.__init__(self, **opts) def addNew(self, typ): self.sigAddNewRequested.emit(self, typ)
class LineScanControl(QtCore.QObject): sigStateChanged = QtCore.Signal(object) def __init__(self, component): QtCore.QObject.__init__(self) self.name = component.name ### These need to be initialized before the ROI is initialized because they are included in stateCopy(), which is called by ROI initialization. self.params = pTypes.SimpleParameter(name=self.name, type='bool', value=True, removable=True, renamable=True, children=[ dict(name='Length', type='float', value=1e-5, suffix='m', siPrefix=True, bounds=[1e-6, None], step=1e-6), dict(name='startTime', type='float', value=5e-2, suffix='s', siPrefix=True, bounds=[0., None], step=1e-2), dict(name='sweepSpeed', type='float', value=1e-6, suffix='m/ms', siPrefix=True, bounds=[1e-8, None], minStep=5e-7, step=0.5, dec=True), dict(name='interSweepSpeed', type='float', value=5e-6, suffix='m/ms', siPrefix=True, bounds=[1e-8, None], minStep=5e-7, step=0.5, dec=True), dict(name='nScans', type='int', value=100, bounds=[1, None]), dict(name='endTime', type='float', value=5.5e-1, suffix='s', siPrefix=True, bounds=[0., None], step=1e-2, readonly=True), ]) self.params.component = weakref.ref(component) self.roi = MultiLineScanROI( [[0.0, 0.0], [self.params['Length'], self.params['Length']]]) self.roi.sigRegionChangeFinished.connect(self.updateFromROI) self.params.sigTreeStateChanged.connect(self.update) def getGraphicsItems(self): return [self.roi] def isActive(self): return self.params.value() def setVisible(self, vis): if vis: self.roi.setOpacity( 1.0 ) ## have to hide this way since we still want the children to be visible for h in self.roi.handles: h['item'].setOpacity(1.0) else: self.roi.setOpacity(0.0) for h in self.roi.handles: h['item'].setOpacity(0.0) def parameters(self): return self.params def update(self): pts = self.roi.listPoints() scanTime = 0. interScanFlag = False for k in xrange(len(pts)): # loop through the list of points k2 = k + 1 if k2 > len(pts) - 1: k2 = 0 dist = (pts[k] - pts[k2]).length() if interScanFlag is False: scanTime += dist / (self.params['sweepSpeed'] * 1000.) else: scanTime += dist / (self.params['interSweepSpeed'] * 1000.) interScanFlag = not interScanFlag self.params['endTime'] = self.params['startTime'] + ( self.params['nScans'] * scanTime) self.setVisible(self.params.value()) def updateFromROI(self): self.update() def generateTask(self): points = self.roi.listPoints() # in local coordinates local to roi. points = [self.roi.mapToView(p) for p in points ] # convert to view points (as needed for scanner) points = [(p.x(), p.y()) for p in points ] ## make sure we can write this data to HDF5 eventually.. return { 'type': self.name, 'active': self.isActive(), 'points': points, 'startTime': self.params['startTime'], 'sweepSpeed': self.params['sweepSpeed'], 'endTime': self.params['endTime'], 'interSweepSpeed': self.params['interSweepSpeed'], 'nScans': self.params['nScans'] }
class RectScanControl(QtCore.QObject): sigStateChanged = QtCore.Signal(object) def __init__(self, component): QtCore.QObject.__init__(self) ### These need to be initialized before the ROI is initialized because they are included in stateCopy(), which is called by ROI initialization. self.blockUpdate = False self.component = weakref.ref(component) self.params = RectScanParameter() self.params.component = self.component self.roi = RectScanROI( size=[self.params['width'], self.params['height']], pos=[0.0, 0.0]) self.params.sigTreeStateChanged.connect(self.paramsChanged) self.roi.sigRegionChangeFinished.connect(self.roiChanged) self.paramsChanged() def getGraphicsItems(self): return [self.roi] def isActive(self): return self.params.value() # def setVisible(self, vis): # if vis: # self.roi.setOpacity(1.0) ## have to hide this way since we still want the children to be visible # for h in self.roi.handles: # h['item'].setOpacity(1.0) # else: # self.roi.setOpacity(0.0) # for h in self.roi.handles: # h['item'].setOpacity(0.0) def updateVisibility(self): v = self.params.value() and self.component().program().isVisible() self.roi.setVisible(v) def parameters(self): return self.params def paramsChanged(self, param=None, changes=None): self.update() def update(self): try: self.params.sigTreeStateChanged.disconnect(self.paramsChanged) reconnect = True except TypeError: reconnect = False try: self.params.system.sampleRate = self.component().program( ).sampleRate self.params.system.downsample = self.component().program( ).downsample self.params.updateSystem() try: oswidth = np.linalg.norm(self.params.system.osVector) self.roi.setOverScan(oswidth) except RuntimeError: self.roi.setOverScan(0) self.updateVisibility() finally: if reconnect: self.params.sigTreeStateChanged.connect(self.paramsChanged) def roiChanged(self): """ read the ROI rectangle width and height and repost in the parameter tree """ state = self.roi.getState() w, h = state['size'] # Remember: ROI origin is in bottom-left because camera module has +y pointing upward. self.params.system.p0 = pg.Point(self.roi.mapToView(pg.Point( 0, h))) # top-left self.params.system.p1 = pg.Point(self.roi.mapToView(pg.Point( w, h))) # rop-right self.params.system.p2 = pg.Point(self.roi.mapToView(pg.Point( 0, 0))) # bottom-left self.params.updateSystem() def saveState(self): task = { 'name': self.params.name(), 'active': self.isActive(), 'roi': self.roi.saveState(), 'scanInfo': self.params.saveState(), } return task def restoreState(self, state): state = state.copy() try: self.params.sigTreeStateChanged.disconnect(self.paramsChanged) self.params.setName(state['name']) self.params.setValue(state['active']) self.params.restoreState(state['scanInfo']) finally: self.params.sigTreeStateChanged.connect(self.paramsChanged) self.roi.setState(state['roi'])