Lab::Measurement::Developer - Lab::Measurement developer tutorial
version 3.662
The driver infrastructure is based on Moose. For Moose basics see e.g.
The Modern Perl book by chromatic, available online for free, contains a chapter on Moose.
For full details, see the very well written Moose::Manual.
We start with a section of code from the Lab::Moose::Instrument::SR830 LIA driver and discuss the most important steps. This explains the most important parts of a driver, i.e. initialization, getters, setters, caching, ...
package Lab::Moose::Instrument::SR830; use 5.010; use Moose; use MooseX::Params::Validate; use Lab::Moose::Instrument qw/validated_getter validated_setter/; use Lab::Moose::Instrument::Cache; use Carp; use namespace::autoclean; our $VERSION = '3.520'; # (1) extends 'Lab::Moose::Instrument'; # (2) with qw/Lab::Moose::Instrument::Common/; # (3) sub BUILD { my $self = shift; $self->clear(); $self->cls(); } # (4) cache amplitude => (getter => 'get_amplitude'); # (5) sub get_amplitude { my ($self, %args) = validated_getter(\@_); # (6) return $self->cached_amplitude( $self->query( command => 'SLVL?', %args ) ); } sub set_amplitude { # (7) my ( $self, $value, %args ) = validated_setter( \@_, value => { isa => 'Num' } ); # (8) $self->write( command => "SLVL $value", %args ); $self->cached_amplitude($value); } # (9) __PACKAGE__->meta()->make_immutable(); 1;
extends 'Lab::Moose::Instrument';
All drivers inherit from Lab::Moose::Instrument. This base class provides the access to the underlying connection via methods like write, query and clear.
write
query
clear
with qw/Lab::Moose::Instrument::Common/;
The Lab::Moose::Instrument::Common role contains methods for GPIB common commands like *IDN, *RST, *CLS, ...
sub BUILD { my $self = shift; $self->clear(); $self->cls(); }
This BUILD method (see Moose::Manual::Construction) executes a device clear and clears the error status.
BUILD
cache amplitude => (getter => 'get_amplitude');
Accessing instruments settings by querying them from the device can be slow. It is mutch faster if the setters and getters store the setting in an object attribute (See Moose::Manual::Attributes). This line creates an attribute for storing the amplitude value of the LIA's reference output.
The attribute can then be accessed with the cached_amplitude method.
cached_amplitude
If the getter is called while the attributes is unset, the get_amplitude method will be called under the hood to initialize the attribute.
get_amplitude
What if the initialization should call the get_amplitude method with additional arguments, say timeout => 10? This can be done by overwriting the builder method of the attribute in your driver:
timeout => 10
sub cached_amplitude_builder { my $self = shift; return $self->get_amplitude( timeout => 10 ); }
See Lab::Moose::Instrument::Cache for full details.
sub get_amplitude { my ($self, %args) = validated_getter(\@_);
We come to the getter function, which queries the amplitude from the LIA. The validated_getter function (from Lab::Moose::Instrument) allows the user to pass additional options, like a timeout, to the underlying connection:
validated_getter
my $amplitude = $self->get_amplitude(timeout => 10); my $amplitude = $self->get_amplitude(); # Use default timeout.
return $self->cached_amplitude( $self->query( command => 'SLVL?', %args ) );
We read the amplitude from the instrument and store it's value into the cache. Don't forget the %args argument to query!
%args
sub set_amplitude { my ( $self, $value, %args ) = validated_setter( \@_, value => { isa => 'Num' } );
The validated_setter function parses the arguments of the setter method. We require that the value argument is a number.
validated_setter
$self->write( command => "SLVL $value", %args ); $self->cached_amplitude($value);
We pass the new amplitude to the instrument and update the cache.
__PACKAGE__->meta()->make_immutable();
Every Moose class shell end this way. See Moose::Manual::BestPractices.
Lab::Moose has extensive support to build automated tests for instrument drivers and this is what enables long-term maintainability of the code base.
If you are new to automated testing with Perl, consider the Modern Perl book, which covers all of the basics.
A test file t/Moose/Instrument/SR830.t for the above driver could look like this:
#!perl use warnings; use strict; use lib 't'; use Lab::Test import => [qw/set_get_test/]; use Moose::Instrument::MockTest qw/mock_instrument/; use MooseX::Params::Validate; use File::Spec::Functions 'catfile'; my $log_file = catfile(qw/t Moose Instrument SR830.yml/); my $lia = mock_instrument( type => 'SR830', log_file => $log_file, ); isa_ok( $lia, 'Lab::Moose::Instrument::SR830' ); $lia->rst( timeout => 10 ); # Test the amplitude getter and setter set_get_test( instr => $lia, values => [qw/0.004 1 2 3 5/], getter => 'get_amplitude', setter => 'set_amplitude', cache => 'cached_amplitude', ); $lia->rst(); done_testing();
First thing, we need to run the test with the real instrument, to create the connection log file t/Moose/Instrument/SR830.yml:
$ perl -Ilib t/Moose/Instrument/SR830.t --connection=LinuxGPIB --connection-options='{pad: 1}'
where the argument of --connection-options is given as a YAML hash.
--connection-options
You can always print a help screen of command line options supported by the test:
$ perl -Ilib t/Moose/Instrument/SR830.t --help
Now with the connection log in place, you can run the test without the real instrument connected:
$ prove -lv t/Moose/Instrument/SR830.t
If set_get_test is not enough for you, take a look at the other test routines in t/Lab/Test.pm which offer
set_get_test
Floating point number comparison (absolute error, relative error, ...)
File comparison, including basic filtering options.
The file xt/pre-commit.pl provides a git pre-commit hook.
The hook is enabled by creating a link to .git/hooks/pre-commit:
ln -s xt/pre-commit.pl .git/hooks/pre-commit
The hook performs the following actions before a commit is finished:
Run perltidy with our configuration perltityrc on all changed files.
Run all tests in t/ with prove.
Run Perl::Critic tests in xt/critic.
Run xt/pod-manual-coverage.t, which ensures that Lab::Measurement::Manual contains links to all modules in the distribution.
If a tests fails, the commit is stopped.
TODO
This software is copyright (c) 2018 by the Lab::Measurement team; in detail:
Copyright 2017-2018 Andreas K. Huettel, 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.