File Coverage

blib/lib/Lab/XPRESS/Sweep/Time.pm
Criterion Covered Total %
statement 17 79 21.5
branch 0 20 0.0
condition 0 6 0.0
subroutine 6 12 50.0
pod 1 6 16.6
total 24 123 19.5


line stmt bran cond sub pod time code
1             package Lab::XPRESS::Sweep::Time;
2             #ABSTRACT: Simple time-controlled repeater
3             $Lab::XPRESS::Sweep::Time::VERSION = '3.880';
4 1     1   2819 use v5.20;
  1         4  
5              
6 1     1   6 use Lab::XPRESS::Sweep;
  1         1  
  1         25  
7 1     1   4 use Time::HiRes qw/usleep/, qw/time/;
  1         2  
  1         6  
8 1     1   96 use Statistics::Descriptive;
  1         2  
  1         18  
9 1     1   5 use Carp;
  1         2  
  1         61  
10 1     1   7 use strict;
  1         2  
  1         834  
11              
12             our @ISA = ('Lab::XPRESS::Sweep');
13              
14             sub new {
15 0     0 0   my $proto = shift;
16 0           my @args = @_;
17 0   0       my $class = ref($proto) || $proto;
18              
19             # define default values for the config parameters:
20             my $self->{default_config} = {
21 0           id => 'Time_sweep',
22             interval => 1,
23             points => [0], #[0,10],
24             duration => undef,
25             stepwidth => 1,
26             mode => 'continuous',
27             allowed_instruments => [undef],
28             allowed_sweep_modes => ['continuous'],
29              
30             stabilize => 0,
31             sensor => undef,
32             sensor_args => [],
33             std_dev_sensor => 1e-6,
34             stabilize_observation_time => 3 * 60,
35             };
36              
37 0 0         if ( ref( @args[0]->{duration} ) ne "ARRAY" ) {
38 0           @args[0]->{duration} = [ @args[0]->{duration} ];
39             }
40              
41 0           foreach my $d ( @{ @args[0]->{duration} } ) {
  0            
42 0           push( @{ $self->{default_config}->{points} }, $d );
  0            
43             }
44              
45             # create self from Sweep basic class:
46 0           $self = $class->SUPER::new( $self->{default_config}, @args );
47 0           bless( $self, $class );
48              
49             # check and adjust config values if necessary:
50 0           $self->check_config_paramters();
51              
52             # init mandatory parameters:
53 0           $self->{DataFile_counter} = 0;
54 0           $self->{DataFiles} = ();
55              
56 0           $self->{stabilize}->{data} = ();
57              
58 0           return $self;
59             }
60              
61             sub check_config_paramters {
62 0     0 0   my $self = shift;
63              
64             # No Backsweep allowed; adjust number of Repetitions if Backsweep is 1:
65 0 0         if ( $self->{config}->{backsweep} == 1 ) {
66 0           $self->{config}->{repetitions} /= 2;
67 0           $self->{config}->{backsweep} = 0;
68             }
69              
70             # Set loop-Interval to Measurement-Interval:
71 0           $self->{loop}->{interval} = $self->{config}->{interval};
72              
73             # check correct initialization of stabilize
74 0 0         if ( $self->{config}->{stabilize} == 1 ) {
75 0 0         if ( not defined $self->{config}->{sensor} ) {
76 0           croak('Stabilization activated, but no sensor defined!');
77             }
78              
79             }
80              
81             }
82              
83             sub exit_loop {
84 0     0 0   my $self = shift;
85              
86 0 0 0       if (
    0          
87 0           @{ $self->{config}->{points} }[ $self->{sequence} ] > 0
88             and $self->{iterator} >= (
89 0           @{ $self->{config}->{points} }[ $self->{sequence} ]
90 0           / @{ $self->{config}->{interval} }[ $self->{sequence} ]
91             )
92             ) {
93 0 0         if (
94             not
95 0           defined @{ $self->{config}->{points} }[ $self->{sequence} + 1 ] )
96             {
97 0 0         if ( $self->{config}->{stabilize} == 1 ) {
98 0           carp('Reached maximum stabilization time.');
99             }
100 0           return 1;
101             }
102              
103 0           $self->{iterator} = 0;
104 0           $self->{sequence}++;
105 0           return 0;
106             }
107             elsif ( $self->{config}->{stabilize} == 1 ) {
108 0           my @sensor_args = @{ $self->{config}->{sensor_args} };
  0            
109             push(
110 0           @{ $self->{stabilize}->{data} },
111 0           $self->{config}->{sensor}->get_value(@sensor_args)
112             );
113              
114 0           my $SENSOR_STD_DEV_PRINT = '-' x 10;
115 0           say "ELAPSED: " . sprintf( '%.2f', $self->{Time} );
116              
117 0 0         if ( $self->{Time} >= $self->{config}->{stabilize_observation_time} )
118             {
119 0           shift( @{ $self->{stabilize}->{data} } );
  0            
120              
121 0           my $stat = Statistics::Descriptive::Full->new();
122 0           $stat->add_data( $self->{stabilize}->{data} );
123 0           my $SENSOR_STD_DEV = $stat->standard_deviation();
124 0           $SENSOR_STD_DEV_PRINT = sprintf( '%.3e', $SENSOR_STD_DEV );
125              
126             say "CURRENT_STDD: "
127             . $SENSOR_STD_DEV_PRINT
128             . " / TARGET_STDD: "
129 0           . sprintf( '%.3e', $self->{config}->{std_dev_sensor} );
130              
131 0 0         if ( $SENSOR_STD_DEV <= $self->{config}->{std_dev_sensor} ) {
132 0           carp('Reached stabilization criterion.');
133 0           return 1;
134             }
135             }
136              
137 0           return 0;
138             }
139             else {
140 0           return 0;
141             }
142             }
143              
144             sub get_value {
145 0     0 1   my $self = shift;
146 0           return $self->{Time};
147             }
148              
149             sub go_to_sweep_start {
150 0     0 0   my $self = shift;
151              
152 0           $self->{sequence}++;
153             }
154              
155             sub halt {
156 0     0 0   return shift;
157             }
158              
159             1;
160              
161             __END__
162              
163             =pod
164              
165             =encoding UTF-8
166              
167             =head1 NAME
168              
169             Lab::XPRESS::Sweep::Time - Simple time-controlled repeater
170              
171             =head1 VERSION
172              
173             version 3.880
174              
175             =head1 SYNOPSIS
176              
177             use Lab::Measurement;
178            
179             my $time_sweep = Sweep('Time',
180             {
181             duration => 5
182             });
183              
184             =head1 DESCRIPTION
185              
186             Parent: Lab::XPRESS::Sweep
187              
188             The Lab::XPRESS::Sweep::Time class implements a simple time controlled repeater module in the Lab::XPRESS::Sweep framework.
189              
190             =head1 CONSTRUCTOR
191              
192             my $time_sweep = Sweep('Time',
193             {
194             duration => 5,
195             interval => 0.5
196             });
197              
198             Instantiates a new Time-Sweep with a duration of 5 seconds and a Measurement interval of 5 seconds.
199             To operate in the stabilization mode make an instant like the following:
200              
201             my $time_sweep = Sweep('Time',
202             {
203             stabilize => 1,
204             sensor => $DIGITAL_MULTIMETER,
205             std_dev_sensor => 1e-6,
206             stabilize_observation_time => 3*60,
207              
208             duration => 20*60,
209             interval => 0.5
210             });
211              
212             =head1 PARAMETERS
213              
214             =head2 duration [float] (default = 1)
215              
216             duration for the time controlled repeater. Default value is 1, negative values indicate a infinit number of repetitions.
217             In stabilization mode, the duration gives the maximum duration which is waited before the sweep gets interrupted even though the stabilization criterion hasn't been reached yet.
218              
219             =head2 interval [float] (default = 1)
220              
221             interval in seconds for taking measurement points.
222              
223             =head2 id [string] (default = 'Repeater')
224              
225             Just an ID.
226              
227             =head2 delay_before_loop [float] (default = 0)
228              
229             defines the time in seconds to wait after the starting point has been reached.
230              
231             =head2 delay_after_loop [float] (default = 0)
232              
233             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.
234              
235             =head2 stabilize [int] (default = 0)
236              
237             1 = Activate stabilization mode. In this mode the sweep will be interrupted when a stabilization criterion is reached or when the duration expires, whatever is reached first.
238             The variable to stabilize on is the value which is returned by the get_value function corresponding to the instrument handle given to the parameter 'sensor'. The stabilization criterion can be set in 'std_dev_sensor' as a number which has the same unit as the variable, that is supposed to stabilize.
239             When the standard deviation of a time series of the stabilization variable falls below 'std_dev_sensor', the sweep ends. The length of the time window, which is used to calculate the standard deviation is given by 'stabilize_observation_time'. The standarad deviation is not being calculated by the sweep, before the time window isn't filled with data completely.
240             Therefore, the sweep will never last less than 'stabilize_observation_time', unless 'duration' < 'stabilize_observation_time'.
241              
242             0 = Deactivate stabilization mode.
243              
244             =head2 sensor [Lab::Instrument] (default = undef)
245              
246             See 'stabilize'.
247              
248             =head2 std_dev_sensor [float] (default = 1e-6),
249              
250             See 'stabilize'.
251              
252             =head2 stabilize_observation_time [float] (default = 3*60)
253              
254             See 'stabilize'.
255              
256             =head1 CAVEATS/BUGS
257              
258             probably none
259              
260             =head1 SEE ALSO
261              
262             =over 4
263              
264             =item L<Lab::XPRESS::Sweep>
265              
266             =back
267              
268             =head1 COPYRIGHT AND LICENSE
269              
270             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
271              
272             Copyright 2012 Stefan Geissler
273             2013 Andreas K. Huettel, Christian Butschkow, Stefan Geissler
274             2015 Christian Butschkow
275             2016 Simon Reinhardt
276             2017 Andreas K. Huettel
277             2020 Andreas K. Huettel
278              
279              
280             This is free software; you can redistribute it and/or modify it under
281             the same terms as the Perl 5 programming language system itself.
282              
283             =cut