File Coverage

blib/lib/Lab/XPRESS/Data/XPRESS_DataFile.pm
Criterion Covered Total %
statement 153 334 45.8
branch 22 90 24.4
condition 2 6 33.3
subroutine 18 34 52.9
pod 0 25 0.0
total 195 489 39.8


line stmt bran cond sub pod time code
1             package Lab::XPRESS::Data::XPRESS_DataFile;
2             $Lab::XPRESS::Data::XPRESS_DataFile::VERSION = '3.881';
3             #ABSTRACT: XPRESS data file module
4              
5 8     8   113 use v5.20;
  8         30  
6              
7 8     8   48 use strict;
  8         20  
  8         269  
8 8     8   54 use Time::HiRes qw/usleep/, qw/time/;
  8         21  
  8         97  
9 8     8   3451 use Storable qw(dclone);
  8         9946  
  8         577  
10 8     8   3662 use File::Copy;
  8         17025  
  8         514  
11 8     8   4348 use Lab::XPRESS::Data::XPRESS_logger;
  8         30  
  8         299  
12 8     8   5073 use Lab::XPRESS::Sweep;
  8         31  
  8         7550  
13              
14             our $counter = 0;
15             our $GLOBAL_PATH = "./";
16             our $GLOBAL_FOLDER = undef;
17             our $DEFAULT_FOLDER = "MEAS";
18             our $DEFAULT_HEADER = "#";
19              
20             sub new {
21 2     2 0 12 my $proto = shift;
22 2   33     37 my $class = ref($proto) || $proto;
23 2         7 my $self = {};
24 2         6 bless( $self, $class );
25 2         18 $self->{COLUMN_NAMES};
26 2         8 $self->{NUMBER_OF_COLUMNS} = 0;
27 2         12 $self->{COLUMNS} = ();
28 2         7 $self->{BLOCK_NUM} = 0;
29 2         5 $self->{LOG_STARTED} = 0;
30 2         7 $self->{loop}->{interval} = 1;
31 2         5 $self->{loop}->{overtime} = 0;
32              
33 2         6 $self->{autolog} = 1;
34 2         6 $self->{skiplog} = 0;
35              
36 2         4 my $filenamebase = shift;
37              
38 2 50       26 if ( not $filenamebase =~ /(.+)(\..+)\b/ ) {
39 2         8 $filenamebase .= ".dat";
40             }
41              
42 2         5 my $foldername = $DEFAULT_FOLDER;
43 2 50       9 $foldername = shift if @_;
44              
45 2         14 $self->{filenamebase} = $filenamebase;
46              
47 2         7 my @plots = @_;
48 2         6 $self->{plots} = [];
49 2         7 foreach my $plot (@plots) {
50 0         0 $self->add_plot($plot);
51             }
52              
53 2         13 $self->{plot_count} = @plots;
54              
55             # create file-handle:
56             $self->{filenamebase}
57 2         11 = $self->create_folder( $self->{filenamebase}, $foldername );
58              
59 2         16 $self->open_logger( $self->{filenamebase}, $self->{plots} );
60 2         6 $self->{file} = $self->{filenamebase};
61              
62 2         11 return $self;
63              
64             }
65              
66             sub create_folder {
67              
68 2     2 0 6 my $self = shift;
69 2         5 my $filenamebase = shift;
70 2   33     20 my $foldername = shift || $DEFAULT_FOLDER;
71              
72 2         8 $filenamebase =~ s/\\/\//g;
73 2         5 $filenamebase =~ s/\.\///g;
74 2         6 $filenamebase =~ s/\.\.\///g;
75 2         4 $filenamebase =~ s/[a-zA-Z]\:\///g;
76              
77 2         9 my @filename = split( /\//, $filenamebase );
78 2         5 my $filename = pop(@filename);
79              
80 2         7 my $folder = join( '/', @filename );
81              
82 2 50       8 if ( not defined $GLOBAL_FOLDER ) {
83 2 50       33 if ( not -d $GLOBAL_PATH ) {
84 0         0 mkdir $GLOBAL_PATH;
85             }
86              
87             # look for existing files:
88 2         70 opendir( DIR, $GLOBAL_PATH );
89 2         66 my @files = readdir(DIR);
90              
91 2         7 my $max_index = 0;
92 2         6 foreach my $file (@files) {
93              
94 4 50       70 if ( $file =~ /($foldername)_([0-9]+)\b/ ) {
95 0 0       0 if ( $2 > $max_index ) {
96 0         0 $max_index = $2;
97             }
98 0         0 $max_index++;
99             }
100             }
101              
102 2         31 closedir(DIR);
103              
104 2         10 $GLOBAL_PATH =~ s/\/$//;
105 2         16 $GLOBAL_FOLDER
106             = sprintf( "%s/%s_%03d", $GLOBAL_PATH, $foldername, $max_index );
107              
108 2         114 mkdir($GLOBAL_FOLDER);
109              
110 2         21 copy( $0, $GLOBAL_FOLDER );
111              
112 2         1163 $self->create_InfoFile();
113             }
114              
115 2         15 my $folder = $GLOBAL_FOLDER . "/" . $folder;
116              
117 2         12 return $folder . "/" . $filename;
118              
119             }
120              
121             sub create_InfoFile {
122 2     2 0 7 my $self = shift;
123              
124 2 50       134 open( my $LOG, ">" . $GLOBAL_FOLDER . "/Config.txt" )
125             or die "cannot open Config.txt";
126 2         45 print $LOG "Instrument Configuration\n";
127 2         11 print $LOG "-" x 100, "\n\n";
128 2         13 print $LOG $self->timestamp(), "\n";
129 2         13 print $LOG "-" x 100, "\n\n";
130              
131 2         11 foreach my $instrument ( @{Lab::Instrument::REGISTERED_INSTRUMENTS} ) {
132 2         26 print $LOG $instrument->get_id() . " ( "
133             . $instrument->get_name()
134             . " )", "\n\n";
135 2         17 print $LOG $instrument->sprint_config(), "\n";
136 2         92 print $LOG "-" x 100, "\n\n";
137             }
138              
139             }
140              
141             # ------------------------------- CONFIG ---------------------------------------------------------
142             sub add_measurement {
143 2     2 0 25 my $self = shift;
144 2         5 my $methode = shift;
145              
146 2         6 my $name = "measurement";
147 2         6 $self->{measurement} = $methode;
148              
149 2         10 my $package = ref($self) . "_" . $counter++;
150              
151 8     8   78 no strict 'refs';
  8         21  
  8         22289  
152 2         5 *{ $package . "::" . $name } = $methode;
  2         18  
153 2         8 @{ $package . '::ISA' } = ( ref($self) );
  2         46  
154 2         18 bless $self, $package;
155              
156 2         8 return $self;
157             }
158              
159             sub add_header {
160 0     0 0 0 my $self = shift;
161 0         0 my $header = shift;
162              
163 0 0       0 if ( not defined $header ) {
164 0         0 return $self->{HEADER};
165             }
166              
167 0         0 my @header = split( /\n/, $header );
168 0         0 foreach (@header) {
169 0         0 $self->{HEADER} .= "#HEADER#\t" . $_ . "\n";
170             }
171              
172 0         0 return $self;
173             }
174              
175             sub add_config {
176 0     0 0 0 my $self = shift;
177 0         0 my $config = shift;
178              
179 0 0       0 if ( not defined $config ) {
180 0         0 return $self->{CONFIG};
181             }
182              
183 0         0 my @config = split( /\n/, $config );
184 0         0 foreach (@config) {
185 0         0 $self->{HEADER} .= "#CONFIG#\t" . $_ . "\n";
186             }
187              
188 0         0 return $self;
189             }
190              
191             sub add_column {
192 15     15 0 53 my $self = shift;
193 15         23 my $col = shift;
194              
195 15 50       1005 if ( eval "return exists &Lab::XPRESS::Sweep::$col;" ) {
196 0         0 Lab::Exception::Warning->throw(
197             "$col is not an alowed column name. Sorry. \n");
198             }
199              
200 15 100       62 if ( not defined $col ) {
201 11         37 return $self->{COLUMNS};
202             }
203              
204             $self->{COLUMN_NAMES}{$col}
205 4         7 = scalar( keys %{ $self->{COLUMN_NAMES} } ) + 1;
  4         19  
206 4         9 push( @{ $self->{COLUMNS} }, $col );
  4         10  
207 4         9 $self->{NUMBER_OF_COLUMNS} += 1;
208 4         9 $self->{logger}->{COLUMN_NAMES} = $self->{COLUMN_NAMES};
209 4         11 $self->{logger}->{NUMBER_OF_COLUMNS} = $self->{NUMBER_OF_COLUMNS};
210 4         9 return $self;
211             }
212              
213             sub add_plot {
214 0     0 0 0 my $self = shift;
215 0         0 my $plot;
216              
217 0 0       0 if ( ref( @_[0] ) eq 'HASH' ) {
218 0         0 $plot = @_[0];
219             }
220             else {
221 0         0 $plot = shift;
222             }
223              
224 0 0       0 if ( not defined $plot->{'autosave'} ) {
225 0         0 $plot->{'autosave'} = 'last';
226             }
227 0         0 push( @{ $self->{plots} }, $plot );
  0         0  
228             $self->{logger}->{COLUMN_NAMES}
229 0         0 = $self->{COLUMN_NAMES}; # refresh logger->column_names
230 0         0 my $plot_copy = dclone( \%{$plot} );
  0         0  
231 0         0 $self->{logger}->add_plots($plot_copy);
232 0         0 $self->{plot_count}++;
233              
234 0         0 return $self;
235             }
236              
237             sub open_logger {
238 2     2 0 4 my $self = shift;
239 2         6 my $filenamebase = shift;
240 2         3 my $plots = shift;
241              
242 2         5 my $plots_copy = [];
243              
244 2 50       8 if ( defined $plots ) {
245 2         114 my $plots_copy = dclone($plots);
246             }
247              
248             $self->{logger}
249 2         32 = new Lab::XPRESS::Data::XPRESS_logger( $filenamebase, $plots_copy );
250 2         8 $self->{logger}->{COLUMN_NAMES} = $self->{COLUMN_NAMES};
251             }
252              
253             sub change_filenamebase {
254 0     0 0 0 my $self = shift;
255 0         0 my $filenamebase = shift;
256 0 0       0 if ( not $filenamebase =~ /\// ) {
257 0         0 $filenamebase = "./" . $filenamebase;
258             }
259              
260             #$self->{filenamebase} = $filenamebase;
261              
262 0         0 my $old_file = $self->{logger}->{filename};
263 0         0 my $old_directory = $self->{logger}->{directory};
264              
265 0         0 delete $self->{logger};
266 0         0 $self->{LOG_STARTED} = 0;
267              
268 0 0       0 if ( -z $old_file ) {
269 0         0 unlink $old_file;
270             }
271              
272 0         0 $self->open_logger($filenamebase);
273 0         0 $self->{file} = $self->{logger}->{filename};
274              
275 0         0 $self->{logger}->{COLUMN_NAMES} = $self->{COLUMN_NAMES};
276 0         0 $self->{logger}->{NUMBER_OF_COLUMNS} = $self->{NUMBER_OF_COLUMNS};
277              
278 0         0 my $plots_copy = dclone( $self->{plots} );
279 0         0 $self->{logger}->add_plots($plots_copy);
280              
281             }
282              
283             sub start_log {
284 2     2 0 5 my $self = shift;
285              
286 2 50       8 if ( defined $self->{HEADER} ) {
287 0         0 chomp $self->{HEADER};
288 0         0 $self->{logger}->LOG( $self->{HEADER} );
289             }
290 2 50       9 if ( defined $self->{CONFIG} ) {
291 0         0 $self->{logger}->LOG( $self->{CONFIG} );
292             }
293 2 50       5 if ( defined @{ $self->{COLUMNS} }[0] ) {
  2         10  
294 2         6 my $columns = $DEFAULT_HEADER;
295 2         4 $columns .= join( "\t", @{ $self->{COLUMNS} } );
  2         10  
296              
297 2         15 $self->{logger}->LOG($columns);
298             }
299 2         8 $self->{LOG_STARTED} = 1;
300 2         18 return $self;
301             }
302              
303             sub start_block {
304 2     2 0 4 my $self = shift;
305              
306 2 50       9 if ( not $self->{LOG_STARTED} ) {
307 2         12 $self->start_log();
308             }
309              
310 2         15 $self->{BLOCK_NUM} = $self->{logger}->_log_start_block();
311 2         155 print "Data block $self->{BLOCK_NUM}\n";
312              
313 2         15 $self->{loop}->{overtime} = 0;
314 2         6 undef $self->{loop}->{t0};
315              
316 2         9 return 1;
317              
318             }
319              
320             sub set_loop_interval {
321 0     0 0 0 my $self = shift;
322 0         0 my $interval = shift;
323              
324 0         0 $self->{loop}->{interval} = $interval;
325              
326 0         0 return $self;
327              
328             }
329              
330             sub end_loop {
331              
332 0     0 0 0 my $self = shift;
333              
334 0         0 $self->{loop}->{t1} = time();
335              
336 0 0       0 if ( not defined $self->{loop}->{t0} ) {
337 0         0 $self->{loop}->{t0} = time();
338 0         0 return 0;
339             }
340              
341             my $delta_time = ( $self->{loop}->{t1} - $self->{loop}->{t0} )
342 0         0 ; # + $self->{loop}->{overtime};
343 0 0       0 if ( $delta_time > $self->{loop}->{interval} ) {
344 0         0 $self->{loop}->{overtime} = $delta_time - $self->{loop}->{interval};
345 0         0 $delta_time = $self->{loop}->{interval};
346 0         0 warn
347             "WARNING: Measurement Loop takes more time ($self->{loop}->{overtime}) than specified by measurement interval ($self->{loop}->{interval}).\n";
348             }
349             else {
350 0         0 $self->{loop}->{overtime} = 0;
351             }
352 0         0 usleep( ( $self->{loop}->{interval} - $delta_time ) * 1e6 );
353 0         0 $self->{loop}->{t0} = time();
354 0         0 return $delta_time;
355              
356             }
357              
358             sub timestamp {
359              
360 2     2 0 6 my $self = shift;
361             my (
362 2         110 $Sekunden, $Minuten, $Stunden, $Monatstag, $Monat,
363             $Jahr, $Wochentag, $Jahrestag, $Sommerzeit
364             ) = localtime(time);
365              
366 2         10 $Monat += 1;
367 2         6 $Jahrestag += 1;
368 2 50       11 $Monat = $Monat < 10 ? $Monat = "0" . $Monat : $Monat;
369 2 50       9 $Monatstag = $Monatstag < 10 ? $Monatstag = "0" . $Monatstag : $Monatstag;
370 2 50       25 $Stunden = $Stunden < 10 ? $Stunden = "0" . $Stunden : $Stunden;
371 2 50       9 $Minuten = $Minuten < 10 ? $Minuten = "0" . $Minuten : $Minuten;
372 2 50       15 $Sekunden = $Sekunden < 10 ? $Sekunden = "0" . $Sekunden : $Sekunden;
373 2         8 $Jahr += 1900;
374              
375 2         19 return "$Stunden:$Minuten:$Sekunden $Monatstag.$Monat.$Jahr\n";
376              
377             }
378              
379             sub finish_measurement {
380 0     0 0 0 my $self = shift;
381              
382 0         0 my $num_of_plots = @{ $self->{logger}->{plots} };
  0         0  
383 0         0 for ( my $i = 0; $i < $num_of_plots; $i++ ) {
384              
385             # close gnuplot-pipe:
386 0         0 $self->{logger}->{plots}->[$i]->{plotter}->_stop_live_plot();
387             }
388              
389 0         0 $self = $self->{logger}->close_file();
390              
391 0         0 delete $self->{logger};
392 0         0 return $self;
393             }
394              
395             sub save_plot {
396 0     0 0 0 my $self = shift;
397 0         0 my $plot_index = shift;
398 0         0 my $type = shift;
399 0         0 my $filename = shift;
400              
401 0 0       0 if ( not defined $plot_index ) {
    0          
402 0         0 $plot_index = 0;
403             }
404 0         0 elsif ( $plot_index > ( my $num_plots = @{ $self->{logger}->{plots} } ) )
405             {
406 0         0 warn "defined plotnumber $plot_index doesn't exist.";
407             }
408              
409 0 0       0 if ( not defined $filename ) {
410              
411             # create filename for saving plot as eps-file:
412 0         0 $filename = $self->{logger}->{filename};
413 0         0 $filename =~ /(.+)\.(.+)\b/;
414 0         0 $filename = sprintf( "%s_%02d", $1, $plot_index + 1 );
415             }
416              
417 0 0       0 if ( not defined $type ) {
418 0         0 $type = 'png';
419             }
420              
421 0         0 $self->{logger}->{plots}->[$plot_index]->{plotter}->replot();
422             $self->{logger}->{plots}->[$plot_index]->{plotter}
423 0         0 ->save_plot( $type, $filename );
424              
425 0         0 return $self;
426              
427             }
428              
429             sub LOG {
430 44     44 0 75 my $self = shift;
431              
432 44 50       102 if ( $self->{skiplog} == 1 ) {
433 0         0 $self->{skiplog} = 0;
434 0         0 return $self;
435             }
436              
437 44 50       96 if ( not $self->{LOG_STARTED} ) {
438 0         0 $self->start_log();
439             }
440              
441 44 50       95 if ( ref( $_[0] ) eq "HASH" ) {
442 44         138 $self->{logger}->LOG(@_);
443             }
444             else {
445 0         0 $self->{logger}->LOG( \@_ );
446             }
447              
448 44         98 return $self;
449             }
450              
451             sub set_autolog {
452 0     0 0   my $self = shift;
453 0           my $value = shift;
454              
455 0           $self->{autolog} = $value;
456              
457 0           return $self;
458             }
459              
460             sub skiplog {
461 0     0 0   my $self = shift;
462              
463 0           $self->{skiplog} = 1;
464              
465 0           return $self;
466             }
467              
468             sub gnuplot_cmd {
469 0     0 0   my $self = shift;
470 0           my $plot_index = shift;
471 0           my $cmd = shift;
472              
473 0 0         if ( not defined $cmd ) {
474 0           $cmd = $plot_index;
475 0           $plot_index = 0;
476             }
477              
478 0 0         if ( $plot_index > ( my $num_plots = @{ $self->{logger}->{plots} } ) ) {
  0            
479 0           warn "defined plotnumber $plot_index doesn't exist.";
480             }
481              
482 0           $self->{logger}->{plots}->[$plot_index]->{plotter}->gnuplot_cmd($cmd);
483              
484 0           return $self;
485              
486             }
487              
488             sub gnuplot_init_bindings {
489 0     0 0   my $self = shift;
490              
491 0           foreach my $plot ( @{ $self->{logger}->{plots} } ) {
  0            
492 0           $plot->{plotter}->init_gnuplot_bindings();
493             }
494              
495 0           return 1;
496             }
497              
498             sub gnuplot_restart {
499 0     0 0   my $self = shift;
500              
501 0           my $i = 0;
502 0           foreach my $plot ( @{ $self->{logger}->{plots} } ) {
  0            
503 0 0         if ( $plot->{plotter}->{PAUSE} < 0 ) {
504 0           $self->gnuplot_pause();
505             }
506              
507 0           my $gpipe = $plot->{plotter}->{gpipe};
508 0 0         if ( not defined $gpipe ) {
    0          
509             $plot->{plotter} = new Lab::XPRESS::Data::XPRESS_plotter(
510 0           $self->{logger}->{filename}, $plot );
511 0           $plot->{plotter}->{ID} = $i;
512 0           $plot->{plotter}->{FILENAME} = $self->{logger}->{filename};
513             $plot->{plotter}->{COLUMN_NAMES}
514 0           = $self->{logger}->{COLUMN_NAMES};
515             }
516             elsif ( not( my $result = print $gpipe "" ) ) {
517             $plot->{plotter} = new Lab::XPRESS::Data::XPRESS_plotter(
518 0           $self->{logger}->{filename}, $plot );
519 0           $plot->{plotter}->{ID} = $i;
520 0           $plot->{plotter}->{FILENAME} = $self->{logger}->{filename};
521             $plot->{plotter}->{COLUMN_NAMES}
522 0           = $self->{logger}->{COLUMN_NAMES};
523             }
524              
525 0           $plot->{plotter}->init_gnuplot();
526 0           $plot->{plotter}->init_gnuplot_bindings();
527 0           $plot->{plotter}->start_plot( $self->{BLOCK_NUM} );
528              
529 0 0         if ( $plot->{plotter}->{PAUSE} > 0 ) {
530 0           $self->gnuplot_pause();
531             }
532              
533 0           $i++;
534             }
535              
536 0           return 1;
537             }
538              
539             sub gnuplot_pause {
540 0     0 0   my $self = shift;
541              
542 0           foreach my $plot ( @{ $self->{logger}->{plots} } ) {
  0            
543 0           $plot->{plotter}->toggle_pause();
544             }
545              
546 0           return 1;
547             }
548              
549             sub datazone {
550 0     0 0   my $self = shift;
551 0           my $plot_index = shift;
552 0           my $left = shift;
553 0           my $center = shift;
554 0           my $right = shift;
555              
556 0           my $x_min;
557             my $x_max;
558 0           my $y_min;
559 0           my $y_max;
560              
561             my %plot
562 0           = %{ $self->{logger}->{plots}->[$plot_index]->{plotter}->{plot} };
  0            
563 0 0         if ( not defined $plot{'x-min'} ) {
564 0           $x_min = $self->{logger}->{DATA}[ $plot{'x-axis'} - 1 ][0];
565             }
566             else {
567 0           $x_min = $plot{'x-min'};
568             }
569 0 0         if ( not defined $plot{'x-max'} ) {
570 0           $x_max = $self->{logger}->{DATA}[ $plot{'x-axis'} - 1 ][1];
571             }
572             else {
573 0           $x_max = $plot{'x-max'};
574             }
575 0 0         if ( not defined $plot{'y-min'} ) {
576 0           $y_min = $self->{logger}->{DATA}[ $plot{'y-axis'} - 1 ][0];
577             }
578             else {
579 0           $y_min = $plot{'y-min'};
580             }
581 0 0         if ( not defined $plot{'y-max'} ) {
582 0           $y_max = $self->{logger}->{DATA}[ $plot{'y-axis'} - 1 ][1];
583             }
584             else {
585 0           $y_max = $plot{'y-max'};
586             }
587             $self->{logger}->{plots}->[$plot_index]->{plotter}
588 0           ->datazone( $x_min, $x_max, $y_min, $y_max, $left, $center, $right );
589              
590 0           return $self;
591              
592             }
593              
594             sub DESTROY {
595 0     0     my $self = shift;
596 0 0         if ( $self->{writer} ) {
597 0           $self->finish_measurement();
598             }
599             }
600              
601             1;
602              
603             __END__
604              
605             =pod
606              
607             =encoding UTF-8
608              
609             =head1 NAME
610              
611             Lab::XPRESS::Data::XPRESS_DataFile - XPRESS data file module
612              
613             =head1 VERSION
614              
615             version 3.881
616              
617             =head1 COPYRIGHT AND LICENSE
618              
619             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
620              
621             Copyright 2012 Stefan Geissler
622             2013 Alois Dirnaichner, Andreas K. Huettel, Christian Butschkow, Stefan Geissler
623             2014 Christian Butschkow
624             2016 Simon Reinhardt
625             2017 Andreas K. Huettel, Simon Reinhardt
626             2020 Andreas K. Huettel, Simon Reinhardt
627              
628              
629             This is free software; you can redistribute it and/or modify it under
630             the same terms as the Perl 5 programming language system itself.
631              
632             =cut