File Coverage

blib/lib/Lab/XPRESS/Sweep/Level.pm
Criterion Covered Total %
statement 47 77 61.0
branch 6 16 37.5
condition 2 6 33.3
subroutine 11 13 84.6
pod 1 7 14.2
total 67 119 56.3


line stmt bran cond sub pod time code
1             package Lab::XPRESS::Sweep::Level;
2             $Lab::XPRESS::Sweep::Level::VERSION = '3.881';
3             #ABSTRACT: Level (e.g. Voltage or Current) sweep
4              
5 2     2   1698 use v5.20;
  2         9  
6              
7 2     2   13 use Lab::XPRESS::Sweep;
  2         4  
  2         59  
8 2     2   11 use Time::HiRes qw/usleep/, qw/time/;
  2         4  
  2         21  
9 2     2   282 use warnings;
  2         4  
  2         65  
10 2     2   14 use strict;
  2         6  
  2         49  
11 2     2   10 use Carp;
  2         3  
  2         2009  
12             our @ISA = ('Lab::XPRESS::Sweep');
13              
14             sub new {
15 1     1 0 3 my $proto = shift;
16 1         3 my @args = @_;
17 1   33     6 my $class = ref($proto) || $proto;
18             my $self->{default_config} = {
19 1         14 id => 'Level_sweep',
20             filename_extension => 'Level=',
21             interval => 1,
22             points => [],
23             duration => [],
24             mode => 'continuous',
25             jump => 0,
26             allowed_instruments => [
27             qw/
28             Lab::Instrument::Yokogawa7651 Lab::Instrument::Keithley2400
29             Lab::Instrument::YokogawaGS200 Lab::Instrument::DummySource
30             Lab::Instrument::SR830::AuxOut Lab::Moose::Instrument::DummySource
31             Lab::Moose::Instrument::YokogawaGS200 Lab::Moose::Instrument::ZI_MFLI Lab::Moose::Instrument::ZI_MFIA/
32             ],
33             allowed_sweep_modes => [ 'continuous', 'list', 'step' ],
34             number_of_points => [undef]
35             };
36              
37 1         27 $self = $class->SUPER::new( $self->{default_config}, @args );
38 1         2 bless( $self, $class );
39              
40 1         4 return $self;
41             }
42              
43             sub go_to_sweep_start {
44 1     1 0 2 my $self = shift;
45              
46             # go to start:
47 1         8 print "Setting level to start value ... ";
48 1 50 33     25 if ( $self->{config}->{mode} =~ /step|list/
49             && $self->{config}->{jump} ) {
50 1         4 my $target = $self->{config}{points}[ $self->{iterator} ];
51 1         2 my $rate = $self->{config}{rate}[ $self->{iterator} ];
52 1         4 my $current = $self->{config}{instrument}->get_level();
53 1         6 my $stepwidth = $self->{config}{stepwidth}[ $self->{iterator} ];
54 1 50       5 if ( not defined $stepwidth ) {
55 0         0 croak "no 'stepwidth' defined for sweep with mode 'step'";
56             }
57 1         5 my $time = abs( ( $target - $current ) / $rate );
58             $self->{config}{instrument}
59 1         10 ->sweep_to_level( $target, $time, $stepwidth );
60             }
61             else {
62             $self->{config}->{instrument}->config_sweep(
63             {
64             'points' =>
65 0         0 @{ $self->{config}->{points} }[ $self->{iterator} ],
66 0         0 'rate' => @{ $self->{config}->{rate} }[ $self->{iterator} ]
  0         0  
67             }
68             );
69 0         0 $self->{config}->{instrument}->trg();
70 0         0 $self->{config}->{instrument}->wait();
71             }
72 1         39 print "Done \n";
73              
74             }
75              
76             sub start_continuous_sweep {
77 0     0 0 0 my $self = shift;
78              
79             $self->{config}->{instrument}->config_sweep(
80             {
81             'points' =>
82 0         0 @{ $self->{config}->{points} }[ $self->{iterator} + 1 ],
83 0         0 'rate' => @{ $self->{config}->{rate} }[ $self->{iterator} + 1 ]
  0         0  
84             }
85             );
86 0         0 $self->{config}->{instrument}->trg();
87             }
88              
89             sub go_to_next_step {
90 11     11 0 19 my $self = shift;
91              
92 11 50       33 if ( $self->{config}->{jump} == 1 ) {
93             $self->{config}->{instrument}->set_level(
94 11         22 ${ $self->{config}->{points} }[ $self->{iterator} ] );
  11         47  
95             }
96             else {
97             $self->{config}->{instrument}->config_sweep(
98             {
99             'points' =>
100 0         0 @{ $self->{config}->{points} }[ $self->{iterator} ],
101 0         0 'rate' => @{ $self->{config}->{rate} }[ $self->{iterator} ]
  0         0  
102             }
103             );
104 0         0 $self->{config}->{instrument}->trg();
105 0         0 $self->{config}->{instrument}->wait();
106             }
107             }
108              
109             sub exit_loop {
110 11     11 0 15 my $self = shift;
111              
112             # if ( not $self->{config}->{instrument}->active() ) {
113 11 50       75 if ( $self->{config}->{mode} =~ /step|list/ ) {
114 11 100       24 if (
115             not
116 11         34 defined @{ $self->{config}->{points} }[ $self->{iterator} + 1 ] )
117             {
118 1         5 return 1;
119             }
120 10         54 return 0;
121             }
122 0 0       0 if ( not $self->{config}->{instrument}->active() ) {
123 0 0       0 if ( $self->{config}->{mode} eq "continuous" ) {
124 0 0       0 if (
125 0         0 not defined @{ $self->{config}->{points} }
126             [ $self->{sequence} + 2 ] ) {
127 0         0 return 1;
128             }
129 0         0 $self->{sequence}++;
130             $self->{config}->{instrument}->config_sweep(
131             {
132 0         0 'points' => @{ $self->{config}->{points} }
133             [ $self->{sequence} + 1 ],
134             'rate' =>
135 0         0 @{ $self->{config}->{rate} }[ $self->{sequence} + 1 ]
  0         0  
136             }
137             );
138 0         0 $self->{config}->{instrument}->trg();
139             }
140 0         0 return 0;
141             }
142             else {
143 0         0 return 0;
144             }
145             }
146              
147             sub get_value {
148 1     1 1 4 my $self = shift;
149 1         7 return $self->{config}->{instrument}->get_level();
150             }
151              
152             sub exit {
153 0     0 0   my $self = shift;
154 0           $self->{config}->{instrument}->abort();
155             }
156              
157             1;
158              
159             __END__
160              
161             =pod
162              
163             =encoding UTF-8
164              
165             =head1 NAME
166              
167             Lab::XPRESS::Sweep::Level - Level (e.g. Voltage or Current) sweep
168              
169             =head1 VERSION
170              
171             version 3.881
172              
173             =head1 SYNOPSIS
174              
175             use Lab::XPRESS::hub;
176             my $hub = new Lab::XPRESS::hub();
177            
178            
179             my $Yoki = $hub->Instrument('Yokogawa7651',
180             {
181             connection_type => 'VISA_GPIB',
182             gpib_address => 2
183             });
184            
185             my $sweep_level = $hub->Sweep('Level',
186             {
187             instrument => $Yoki,
188             points => [-1,1],
189             rate => [0.1,0.001],
190             mode => 'continuous',
191             interval => 1,
192             backsweep => 1
193             });
194              
195             =head1 DESCRIPTION
196              
197             Parent: Lab::XPRESS::Sweep
198              
199             The Lab::XPRESS::Sweep::Level class implements a module for output level Sweeps in the Lab::XPRESS::Sweep framework.
200              
201             =head1 CONSTRUCTOR
202              
203             my $sweep_level = $hub->Sweep('Level',
204             {
205             instrument => $Yoki,
206             points => [-1,1],
207             rate => [0.1,0.001],
208             mode => 'continuous',
209             interval => 1,
210             backsweep => 1
211             });
212              
213             Instantiates a new level-sweep.
214              
215             =head1 PARAMETERS
216              
217             =head2 instrument [Lab::Instrument] (mandatory)
218              
219             Instrument, conducting the sweep. Must be of type Lab:Instrument.
220             Allowed instruments: Lab::Instrument::Yokogawa7651
221              
222             =head2 mode [string] (default = 'continuous' | 'step' | 'list')
223              
224             continuous: perform a continuous level sweep. Measurements will be performed constantly at the time-interval defined in interval.
225              
226             step: measurements will be performed at discrete values of the applied level between start and end points defined in parameter points, seperated by level steps defined in parameter stepwidth
227              
228             list: measurements will be performed at a list level values defined in parameter points
229              
230             =head2 points [float array] (mandatory)
231              
232             array of level values that defines the characteristic points of the sweep.
233             First value is appraoched before measurement begins.
234              
235             Case mode => 'continuous' :
236             List of at least 2 values, that define start and end point of the sweep or a sequence of consecutive sweep-sections (e.g. if changing the sweep-rate for different sections or reversing the sweep direction).
237             points => [-5, 5] # Start: -5 / Stop: 5
238              
239             points => [-5, -1, 1, 5]
240              
241             points => [0, -5, 5]
242              
243             Case mode => 'step' :
244             Same as in 'continuous' but level will be swept in stop and go mode. I.e. level source approaches values between start and stop at the interval defined in 'stepwidth'. A measurement is performed, when level source is idle.
245              
246             Case mode => 'list' :
247             Array of levels, with minimum length 1, that are approached in sequence to perform a measurment.
248              
249             =head2 rate [float array] (mandatory if not defined duration)
250              
251             array of rates, at which the level is swept (V / sec).
252             Has to be of length 1 or greater (Maximum length: length of points-array).
253             The first value defines the rate to approach the starting point.
254             The following values define the rates to approach the levels defined by the points-array.
255             If the number of values in the rates-array is less than the length of the points-array, the last defined rate will be used for the remaining sweep sections.
256              
257             points => [-5, -1, 1, 5],
258             rates => [1, 0.005, 0.02]
259            
260             rate to approach -5 V (the starting point): 1 V/sec
261             rate to approach -1 V : 0.005 V/sec
262             rate to approach 1 V : 0.02 V/sec
263             rate to approach 5 V : 0.02 V/sec (last defined rate)
264              
265             =head2 duration [float array] (mandatory if not defined rate)
266              
267             can be used instead of 'rate'. Attention: Use only the 'duration' or the 'rate' parameter. Using both will cause an Error!
268              
269             The first value defines the duration to approach the starting point.
270             The second value defines the duration to approach the level value defined by the second value of the points-array.
271             ...
272             If the number of values in the duration-array is less than the length of the points-array, last defined duration will be used for the remaining sweep sections.
273              
274             =head2 stepwidth [float array]
275              
276             This parameter is relevant only if mode = 'step' has been selected.
277             Stepwidth has to be an array of length '1' or greater. The values define the width for each step within the corresponding sweep sequence.
278             If the length of the defined sweep sequence devided by the stepwidth is not an integer number, the last step will be smaller in order to reach the defined points-value.
279              
280             points = [0, 0.5, 3]
281             stepwidth = [0.2, 0.5]
282            
283             ==> steps: 0, 0.2, 0.4, 0.5, 1.0, 1.5, 2.0, 2.5, 3
284              
285             =head2 number_of_points [int array]
286              
287             can be used instead of 'stepwidth'. Attention: Use only the 'number_of_points' or the 'stepwidth' parameter. Using both will cause an Error!
288             This parameter is relevant only if mode = 'step' has been selected.
289             Number_of_points has to be an array of length '1' or greater. The values defines the number of steps within the corresponding sweep sequence.
290              
291             points = [0, 0.5, 3]
292             number_of_points = [5, 2]
293            
294             ==> steps: 0, 0.1, 0.2, 0.3, 0.4, 0.5, 1.75, 3
295              
296             =head2 interval [float] (default = 1)
297              
298             interval in seconds for taking measurement points. Only relevant in mode 'continuous'.
299              
300             =head2 backsweep [int] (default = 0 | 1 | 2)
301              
302             0 : no backsweep (default)
303             1 : a backsweep will be performed
304             2 : no backsweep performed automatically, but sweep sequence will be reverted every second time the sweep is started (relevant eg. if sweep operates as a slave. This way the sweep sequence is reverted at every second step of the master)
305              
306             =head2 jump [int] (default = 0 | 1 )
307              
308             can be used to switch off the sweeping between adjacent points in step or list mode.
309              
310             0 : a sweep is performed between adjacent steps (default)
311             1 : the level is set without sweeping, given that gateprotect does not trigger a sweep.
312              
313             =head2 id [string] (default = 'Level_sweep')
314              
315             Just an ID.
316              
317             =head2 filename_extention [string] (default = 'V=')
318              
319             Defines a postfix, that will be appended to the filenames if necessary.
320              
321             =head2 delay_before_loop [int] (default = 0)
322              
323             defines the time in seconds to wait after the starting point has been reached.
324              
325             =head2 delay_in_loop [int] (default = 0)
326              
327             This parameter is relevant only if mode = 'step' or 'list' has been selected.
328             Defines the time in seconds to wait after the value for the next step has been reached.
329              
330             =head2 delay_after_loop [int] (default = 0)
331              
332             Defines the time in seconds to wait after the sweep has been finished. This delay will be executed before an optional backsweep or optional repetitions of the sweep.
333              
334             =head1 CAVEATS/BUGS
335              
336             probably none
337              
338             =head1 SEE ALSO
339              
340             =over 4
341              
342             =item L<Lab::XPRESS::Sweep>
343              
344             =back
345              
346             =head1 COPYRIGHT AND LICENSE
347              
348             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
349              
350             Copyright 2012 Stefan Geissler
351             2013 Alois Dirnaichner, Andreas K. Huettel, Christian Butschkow, Stefan Geissler
352             2014 Alois Dirnaichner, Andreas K. Huettel
353             2015 Alois Dirnaichner
354             2016 Simon Reinhardt
355             2017 Andreas K. Huettel, Simon Reinhardt
356             2019 Simon Reinhardt
357             2020 Andreas K. Huettel
358              
359              
360             This is free software; you can redistribute it and/or modify it under
361             the same terms as the Perl 5 programming language system itself.
362              
363             =cut