Lab::Moose::Sweep::Tutorial - Documentation of high-level sweep framework
version 3.622
As a basic example of a 1D sweepm, we measure an IV curve:
# file: IV.pl use Lab::Moose; # you get 'use warnings; use strict;' for free my $source = instrument( type => 'YokogawaGS200', connection_type => 'USB', # Safety limits: max_units => 10, min_units => -10, max_units_per_step => 0.1, max_units_per_second => 1 ); my $dmm = instrument(type => 'Agilent34410A', connection_type => 'USB'); my $sweep = sweep( type => 'Step::Voltage', instrument => $source, from => -5, to => 5, step => 0.01 ); my $datafile = sweep_datafile(columns => [qw/voltage current/]); my $meas = sub { my $sweep = shift; $sweep->log( voltage => $source->cached_level(), current => $dmm->get_value(), ); }; $sweep->start( measurement => $meas, datafile => $datafile, );
Running this script repeatedly creates output folders MEAS_000, MEAS_001, ... The folders contain the following files:
IV.pl
Copy of the measurement script.
META.yml
YAML file with various metadata (time of script run, username, hostname, copy of the used commandline, Lab::Measurement version, ...).
data.dat
Gnuplot-style datafile:
# voltage current -5 42 -4.99 43 ...
To also measure the IV in the reverse direction from -5 to 5 volts, we add the backsweep option:
backsweep
my $sweep = sweep( type => 'Step::Voltage', instrument => $source, from => -5, to => 5, step => 0.01, backsweep => 1, );
You can change the name of the datafolder by providing a folder argument to the start method:
folder
start
$sweep->start( measurement => $meas, datafile => $datafile, folder => 'IV_curve' );
This will create output folders with names IV_curve_xxx.
We can create multiple datafiles:
my $datafile1 = sweep_datafile( filename => 'data1', columns => [qw/voltage current/] ); my $datafile2 = sweep_datafile( filename => 'data2', columns => [qw/voltage current/] ); $sweep->start( measurement => $meas, datafiles => [$datafile1, $datafile2], folder => 'IV_curve' );
And in the $meas subroutine, call the sweeps's log method for both datafiles:
$meas
log
my $meas = sub { my $sweep = shift; my $voltage = $source->cached_level(); $sweep->log( datafile => $datafile1, voltage => $voltage, current => $dmm1->get_value(), ); $sweep->log( datafile => $datafile2, voltage => $voltage, current => $dmm2->get_value() ); };
Let us start with a simple 2D sweep: we sweep a gate voltage (outer sweep) and a bias voltage and again measure a current:
use Lab::Moose; # As we use two Yokogawa's, we need to provide USB serial IDs my $gate_source = instrument( type => 'YokogawaGS200', connection_type => 'USB', connection_options => {serial => '...'}, # Safety limits: max_units => 10, min_units => -10, max_units_per_step => 0.1, max_units_per_second => 1 ); my $bias_source = instrument( type => 'YokogawaGS200', connection_type => 'USB', connection_options => {serial => '...'}, # Safety limits: max_units => 10, min_units => -10, max_units_per_step => 0.1, max_units_per_second => 1 ); my $dmm = instrument(type => 'Agilent34410A', connection_type => 'USB'); my $gate_sweep = sweep( type => 'Step::Voltage', instrument => $gate_source, from => 0, to => 1, step => 0.1 ); my $bias_sweep = sweep( type => 'Step::Voltage', instrument => $bias_source, from => 0, to => 1, step => 0.1 ); my $datafile = sweep_datafile(columns => [qw/gate bias current/]); my $meas = sub { my $sweep = shift; my $v_gate = $gate_source->cached_level(); my $v_bias = $bias_source->cached_level(); $sweep->log( gate => $v_gate, bias => $v_bias, current => $dmm->get_value(), ); }; $gate_sweep->start( slave => $bias_sweep, measurement => $meas, datafile => $datafile, );
By default, this will create a 2D block datafile:
# gate bias current 0 0 x 0 0.1 x 0 0.2 x ... 0 1 x 0.1 0 x 0.1 0.1 x 0.1 0.2 x ... ... 1 0 x ... 1 1 x
Alternatively, we can create multiple 1D datafiles, one for each value of the gate voltage. We do this by setting the datafile_dim parameter to 1:
datafile_dim
$gate_sweep->start( slave => $bias_sweep, measurement => $meas, datafile => $datafile, datafile_dim => 1 );
The output files will be <data_Voltage=0.dat, data_Voltage=0.1.dat, ..., data_Voltage=1.dat> We can customize the Voltage= part in the datafile names by providing a filename extension in the gate sweep:
my $gate_sweep = sweep( type => 'Step::Voltage', instrument => $gate_source, from => 0, to => 1, step => 0.1, filename_extension => 'Gate=', );
If we create sweeps setups with dimension > 2, the maximum datafile dimension remains 2. E.g. if we create a 3D sweep [Temperature, Gate, Bias], a 2D datafile will be created for each value of the temperature sweep. If we set datafile_dim to 1, a subfolder will be created for each value of the temperature and the subfolders contain 1D datafiles for each gate voltage.
FIXME: link to example script.
Let us add a simple line plot to our IV measurement:
my $datafile = sweep_datafile(columns => [qw/voltage current/]); $datafile->add_plot( x => 'voltage', y => 'current', );
This will create a live line plot, which will be updated for each new data point. A copy of the plot will be saved in the output folder in png format with filename "$datafile.png". You can change this filename with the hard_copy option:
"$datafile.png"
hard_copy
$datafile->add_plot( x => 'voltage', y => 'current', hard_copy => 'data.png', );
Let us add a color plot to the gate/bias 2D sweep:
my $datafile = sweep_datafile(columns => [qw/gate bias current/]); $datafile->add_plot( type => 'pm3d', x => 'gate', y => 'bias', z => 'current' );
By default, the live plot will be updated after a bias sweep is completed.
There are many ways to customize a plot and it's hard copy:
If we don't want to use gnuplot's default terminal for the live plot or hard copy, we use the terminal, hard_copy_terminal, terminal_options and hard_copy_terminal_options options:
terminal
hard_copy_terminal
terminal_options
hard_copy_terminal_options
$datafile->add_plot( type => 'pm3d', x => 'gate', y => 'bias', z => 'current', terminal => 'x11', terminal_options => {linewidth => 3}, hard_copy => 'data.jpg', hard_copy_terminal => 'jpeg', hard_copy_terminal_options => {linewidth => 0.5} );
PDL::Graphics::Gnuplot separates between plot options and curve options:
$datafile->add_plot( type => 'pm3d', x => 'gate', y => 'bias', z => 'current', plot_options => { title => 'x - y plot', xlabel => 'x (V)', ylabel => 'y (V)', cblabel => 'current (A)', # label for color box format => {x => "'%.2e'", y => "'%.2e'"}, grid => 0, # disable grid }, curve_options => { with => 'lines', # default is 'points' linetype => 2, # color linewidth => 2, }, );
More Plot and curve options are documented in PDL::Graphics::Gnuplot.
There are types of instruments which return more than a single data. Examples are spectrum and network analyzers, which perform a frequency sweep and return an array of data after each sweep.
The sparam_sweep method provided, e.g., by the Lab::Moose::Instrument::RS_ZVA returns a 2D PDL with the following format:
sparam_sweep
[ [freq1 , freq2 , ..., freqN ], [Re(S11)_1, Re(S11)_2, ..., Re(S11)_N], [Im(S11)_1, Im(S11)_2, ..., Im(S11)_N], [Amp_1 , Amp_2 , ..., Amp_N ], [phase_1 , phase_2 , ..., phase_N ], ]
The following script sweeps a voltage source and performs a frequency sweep with the VNA for each level of the voltage source. Each VNA sweep is logged into a separate datafile which contains one line of data for each frequency point.
use Lab::Moose; my $source = instrument( type => 'YokogawaGS200', connection_type => 'USB', # Safety limits: max_units => 10, min_units => -10, max_units_per_step => 0.1, max_units_per_second => 1 ); my $vna = instrument( type => 'RS_ZVA', connection_type => 'VXI11', connection_options => {host => '192.168.x.x'}, ); my $sweep = sweep( type => 'Step::Voltage', instrument => $source, from => -5, to => 5, step => 0.01 ); my $datafile = sweep_datafile( columns => [qw/voltage freq Re_S21 Im_S21 amplitude phase/]); my $meas = sub { my $sweep = shift; my $voltage = $source->cached_level(); my $block = $vna->sparam_sweep(timeout => 10, average => 100); $sweep->log_block( prefix => {voltage => $voltage}, block => $block ); }; $sweep->start( measurement => $meas, datafile => $datafile, datafile_dim => 1, # each VNA trace in a separate file point_dim => 1, # the measurement sub logs blocks, not points );
Without the point_dim => 1 setting, only one datafile would be generated. One could also log all blocks into a single 2D datafile by setting datafile_dim => 2.
point_dim => 1
datafile_dim => 2
With continuous sweeps, the sweep parameter is ramped in the background while data is recorded. This is in constrast with step/list sweeps where the sweep parameter is kept constant during data acquisition. The rate of measurement points taken is controlled by the interval sweep attribute.
interval
For example, the following time sweep records data every 0.5 seconds and finishes after 60 seconds:
use Lab::Moose; my $sweep = sweep( type => 'Continuous::Time', interval => 0.5, duration => 60 );
Note that the rate is given in Tesla/min.
my $sweep = sweep( type => 'Continuous::Magnet', instrument => $ips, from => -1, # Tesla to => 1, rate => 0.1, # (Tesla/min, always positive) start_rate => 1, # (optional, rate to approach start point) interval => 0.5, # one measurement every 0.5 seconds );
These attributes can be used to introduce delays into a sweep:
my $sweep = sweep( type => 'Step::Voltage', instrument => $source, from => -5, to => 5, step => 0.01, delay_before_loop => 1.5, delay_in_loop => 0.1, delay_after_loop => 2.5, );
With delay_before_loop set, the sweep will sleep 1.5 seconds before starting the sweep (after going to the start point of the sweep). With delay_in_loop set, there is a sleep between going to the setpoint and calling the measurement subroutine. The delay_after_loop causes a delay between finishing the sweep and going back to the start point.
delay_before_loop
delay_in_loop
delay_after_loop
The before_loop coderef is used to execute arbitrary code at the start of a sweep:
before_loop
my $before_loop = sub { print("will start loop now\n"); }; my $sweep = sweep( type => 'Step::Voltage', instrument => $source, from => -5, to => 5, step => 0.01, before_loop => $before_loop, );
The $before_loop code is called after a possible delay_before_loop delay.
$before_loop
This software is copyright (c) 2018 by the Lab::Measurement team; in detail:
Copyright 2018 Simon Reinhardt
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Lab::Measurement, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Lab::Measurement
CPAN shell
perl -MCPAN -e shell install Lab::Measurement
For more information on module installation, please visit the detailed CPAN module installation guide.