def fetch(filename, nevents, runattrs=None): """ Fetch and save waveform traces from the oscilloscope. Args: - filename: str Filename to store traces in (in hdf5 format). - nevents: int Number of triggered events to save in `filename`. """ scope = LeCroyScope(setup.scope_ip, timeout=20.0) # turn off the display scope.send('display off') scope.check_last_command() # clear the output queue scope.clear() # get active channels channels = scope.getchannels() # get scope configuration settings = get_settings(scope) # get wave descriptors for each channel # important to do this before queue is primed! # need to trigger in order to get correct wave_array_count scope.trigger() time.sleep(5.0) wavedesc = {} for channel in channels: wavedesc[channel] = scope.getwavedesc(channel) # open up the output file f = h5py.File(filename, 'w') # set scope configuration for command, setting in settings.items(): f.attrs[command] = setting if 'ON' in f.attrs['SEQUENCE']: sequence_count = int(f.attrs['SEQUENCE'].split(',')[1]) if sequence_count < 1: raise Exception('sequence count must be a positive number.') else: sequence_count = 1 for channel in channels: nsamples = wavedesc[channel]['wave_array_count'] // sequence_count f.create_dataset('channel%i' % channel, (nevents, nsamples), dtype=wavedesc[channel]['dtype'], chunks=(max(1, min(100, nevents // 100)), nsamples), compression='gzip') for key, value in wavedesc[channel].items(): try: f['channel%i' % channel].attrs[key] = value except ValueError: pass if runattrs is not None: for name in runattrs: for key, value in runattrs[name].items(): f[name].attrs[key] = value # start a timer time0 = time.time() try: i = 0 while True: print '\rsaving event: %i' % i, sys.stdout.flush() try: scope.trigger() for channel in channels: wave_array = scope.getwaveform(channel, wavedesc[channel]) if sequence_count > 1: try: f['channel%i' % channel][i:i+sequence_count] = \ wave_array.reshape(sequence_count, wave_array.size//sequence_count) except ValueError: f['channel%i' % channel][i:i+sequence_count] = \ wave_array.reshape(sequence_count, wave_array.size//sequence_count)[:len(f['channel%i' % channel])-i] else: f['channel%i' % channel][i] = wave_array except (socket.error, struct.error) as e: print '\n' + str(e) scope.clear() continue i += sequence_count if i >= nevents: print '\rsaving event: %i' % i, break print except KeyboardInterrupt: print '\nresizing datasets...' for channel in channels: f['channel%i' % channel].resize( (i, wavedesc[channel]['wave_array_count'] // sequence_count)) raise finally: f.close() scope.clear() scope.send('display on') scope.check_last_command() elapsed = time.time() - time0 if i > 0: print 'Completed %i events in %.3f seconds.' % (i, elapsed) print 'Averaged %.5f seconds per acquisition.' % (elapsed / i) print "Wrote to file '%s'." % filename