def sgramTransfer(self, duration=1., nLines=100): ''' Transfers data that has already been taken. Typical usage:: self.sgramInit() ... << some activity >> self.run(False) self.spectrogram() Currently only supports free running mode, so time is approximate. The accuracy of timing and consistency of timing between lines is not guaranteed. ''' if 'SGR' not in self.getMeasurements(): raise Exception( 'Spectrogram is not being recorded. Did you forget to call sgramInit()?') # def qg(subParam): # for Quick Get ''' # return float(self.getConfigParam('SGR:' + subParam, forceHardware=True)) # Create data structure with proper size trialLine = self.__sgramLines([0])[0] nFreqs = len(trialLine) # HOW MANY LINES # Which lines are we actually taking from the equipment estTimePerLine = 15.8e-6 * nFreqs # self.getConfigParam('SGR:TIME:SPEC:PERL', forceHardware=True) # self.setConfigParam('SGR:TIME:STAR:DIV', 0, forceHardware=True) # self.setConfigParam('SGR:TIME:PER:DIV', 0, forceHardware=True) # estTimePerLine = self.getConfigParam('SGR:TIME:PER:DIV', forceHardware=true) downsample = int(duration / estTimePerLine / nLines) if downsample < 1: nLines = int(duration / estTimePerLine) print('Warning: line density too high. You will get {} lines.'.format(nLines)) downsample = 1 lineNos = np.arange(nLines, dtype=int) * downsample # lineNos = np.arange(0,101,1) # nLines = len(lineNos) sgramMat = np.zeros((nLines, nFreqs)) # Transfer data logger.debug('Preparing to transfer spectrogram of shape %s...', sgramMat.shape) self.__sgramLines(lineNos, container=sgramMat, debugEvery=100) logger.debug('Transfer complete.') # Scaling fStart = float(self.getConfigParam('SGR:FREQ:START', forceHardware=True)) fStop = float(self.getConfigParam('SGR:FREQ:STOP', forceHardware=True)) fBasis = np.linspace(fStart, fStop, nFreqs) tBasis = np.linspace(0, duration, nLines) # Put this in some kind of 2-D measured function structure. gram = Spectrogram([fBasis, tBasis], sgramMat) return gram
def open(self): ''' Open connection with 5 retries. ''' if self.mbSession is not None: return if self.address is None: raise RuntimeError("Attempting to open connection to unknown address.") if self.resMan is None: self.resMan = pyvisa.ResourceManager() try: self.mbSession = self.resMan.open_resource(self.address) self.mbSession.write_termination = self.termination if not self.tempSess: logger.debug('Opened %s', self.address) except pyvisa.VisaIOError as err: logger.warning('There was a problem opening the VISA %s... Error code: %s', self.address, err.error_code) if self._open_retries < OPEN_RETRIES: self._open_retries += 1 time.sleep(0.5 * self._open_retries) logger.warning('Trying again... (try = %s/%s)', self._open_retries, OPEN_RETRIES) self.open() else: logger.error(err) raise else: if self._open_retries != 0: logger.warning('Found it!') self._open_retries = 0
def __sgramLines(self, lineNos, container=None, debugEvery=None): if container is None: container = [None] * len(lineNos) VISAInstrumentDriver.open(self) for i, lno in enumerate(lineNos): if debugEvery is not None and i % debugEvery == 0: logger.debug('Transferring %s / %s', lno, lineNos[-1]) self.write('TRAC:SGR:SEL:LINE {}'.format(lno)) for _ in range(2): # Sometimes the query just fails so we try again rawLine = self.mbSession.query_binary_values('FETCH:SGR?') if len(rawLine) > 0: break else: logger.debug('Ran out of data on line %s', lno) continue try: container[i] = rawLine except ValueError as err: print('Error when putting data into container') print('len(rawLine) =', len(rawLine)) print('type(container) =', type(container)) if type(container) == np.ndarray: print('np.shape(container) =', np.shape(container)) else: print('len(container) =', len(container)) VISAInstrumentDriver.close(self) raise err VISAInstrumentDriver.close(self) return container
def sendToHardware(self, waitTime=None): """Updates current drivers with the present value of tuneState Converts it to a raw voltage, depending on the mode of the driver Args: """ # First get a complete array in terms of voltage needed by the NI-PCI card fullVoltageState = np.zeros(self.maxChannel) for ch, baseVal in self.stateDict.items(): fullVoltageState[ch] = self.baseUnit2val(baseVal, 'volt') # Then write a TCPIP packet writeStr = 'Set:' for v in fullVoltageState: writeStr += ' ' + str(v) # self.open() retStr = self.query(writeStr) # self.close() if retStr != 'ACK': raise RuntimeError('Current driver is angry. Message: \"' + retStr + '\"') if waitTime is None: waitTime = self.waitMsOnWrite logger.debug('Current settling for %s ms', waitTime) time.sleep(waitTime / 1000)
def connect(self): ''' Connects to the socket and leaves the connection open. If already connected, does nothing. Returns: socket object. ''' if self._socket is None: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) try: logger.debug("Attempting new connection (timeout = %s)", str(self.timeout)) init_time = time.time() s.settimeout(self.timeout) s.connect((self.ip_address, self.port)) except socket.error: # avoiding shutdown to prevent sending any data to remote socket # https://stackoverflow.com/questions/13109899/does-socket-become-unusable-after-connect-fails # s.shutdown(socket.SHUT_WR) s.close() del s logger.error('Cannot connect to resource.') raise else: final_time = time.time() elapsed_time_ms = 1e3 * (final_time - init_time) logger.debug("Connected. Time elapsed: %s msec", '{:.2f}'.format(elapsed_time_ms)) self._socket = s return self._socket else: return self._socket
def query(self, queryStr, withTimeout=None): '''Read the unmodified string sent from the instrument to the computer. ''' logger.debug('%s - Q - %s', self.address, queryStr) retStr = self.query_raw_binary(queryStr, withTimeout) logger.debug('Query Read - %s', repr(retStr)) return retStr.rstrip()
def check_socket(host, port): # learned from https://stackoverflow.com/questions/19196105/python-how-to-check-if-a-network-port-is-open-on-linux with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: if sock.connect_ex((host, port)) == 0: # pylint: disable=no-member logger.debug("%s:%s socket is open", host, port) port_open = True # Port is open else: port_open = False # Port is closed return port_open
def triggerAcquire(self): """Performs a sweep and reads the data Returns an array of dBm values as doubles :rtype: array """ logger.debug('The OSA is sweeping') self.write('SPTRACESWP0', 'SP_SWEEP_TRACE_0') # activate trace 0 self.write('SPSWP1', 'SP_SINGLE_SWEEP') # Initiates a sweep # self.write('*WAI') # Bus and entire program stall until sweep completes. logger.debug('Done')
def close(self): if self.mbSession is None: return try: self.mbSession.close() except pyvisa.VisaIOError: logger.error('There was a problem closing the VISA %s', self.address) raise self.mbSession = None if not self.tempSess: logger.debug('Closed %s', self.address)
def query(self, queryStr, expected_talker=None): ret = self._query(queryStr) if expected_talker is not None: if ret != expected_talker: log_function = logger.warning else: log_function = logger.debug log_function("'%s' returned '%s', expected '%s'", queryStr, ret, str(expected_talker)) else: logger.debug("'%s' returned '%s'", queryStr, ret) return ret
def write(self, writeStr): try: self.open() try: self.mbSession.write(writeStr) except Exception: logger.error('Problem writing to %s', self.address) raise logger.debug('%s - W - %s', self.address, writeStr) finally: if self.tempSess: self.close()
def _setHardwareConfig(self, subgroup=''): ''' Writes all or a subgroup of commands using the state of the 'live' config. Args: subgroup (str): a subgroup of commands. If '', we write everything ''' self.initHardware() live = self.config['live'].getList(subgroup, asCmd=False) for cmd in live: if not self.colon and cmd[0] == self.separator: cmd = cmd[1:] if not self.space: ''.join(cmd.split(' ')) logger.debug('Sending %s to configurable hardware', cmd) self.write(cmd)
def frequency(self, newFreq=None): sciUnits = ['MZ', 'HZ', 'KHZ', 'MHZ'] def toMultiplier(sciOrder): return 10 ** (3 * (sciOrder - 1)) if newFreq is not None: sciOrder = int(np.ceil(np.log10(newFreq) / 3)) logger.debug('sciOrder = %s', sciOrder) sciUnit = sciUnits[sciOrder] logger.debug('sciUnit = %s', sciUnit) sciFreq = newFreq / toMultiplier(sciOrder) self.setConfigParam('FRQ', '{} {}'.format(sciFreq, sciUnit)) retSciStr = self.getConfigParam('FRQ') retSciElements = retSciStr.split(' ') sciFreq = float(retSciElements[0]) sciUnit = retSciElements[1] realFreq = sciFreq * toMultiplier(sciUnits.index(sciUnit)) return realFreq
def query(self, queryStr, withTimeout=None): retStr = None try: self.open() logger.debug('%s - Q - %s', self.address, queryStr) toutOrig = self.timeout try: if withTimeout is not None: self.timeout = withTimeout retStr = self.mbSession.query(queryStr) if withTimeout is not None: self.timeout = toutOrig except Exception: logger.error('Problem querying to %s', self.address) # self.close() raise retStr = retStr.rstrip() logger.debug('Query Read - %s', retStr) finally: if self.tempSess: self.close() return retStr
def _getHardwareConfig(self, cStrList): ''' Queries all or a subgroup of commands using the state of the 'live' config. This does not return, but it puts it in the config['live'] attribute Args: cStrList (list or str): list of command strings. Can also be a scalar string ''' self.initHardware() if type(cStrList) is not list and type(cStrList) is str: cStrList = [cStrList] for cStr in cStrList: if cStr[-1] == '&': # handle the sibling subdir token cStr = cStr[:-2] try: ret = self.query(cStr + '?') except VisaIOError: logger.error( 'Problematic parameter was %s.\n' 'Likely it does not exist in this instrument command structure.', cStr) raise logger.debug('Queried %s, got %s', cStr, ret) if self.header: val = ret.split(' ')[-1] else: val = ret # Type detection try: val = float(val) except ValueError: pass else: if val == floor(val): val = int(val) self.config['live'].set(cStr, val)
def startup(self): visalogger.debug("%s.startup method empty", self.__class__.__name__)