File Coverage

blib/lib/Lab/Moose/Instrument/RS_FSV.pm
Criterion Covered Total %
statement 42 43 97.6
branch 3 4 75.0
condition 1 3 33.3
subroutine 10 10 100.0
pod 1 2 50.0
total 57 62 91.9


line stmt bran cond sub pod time code
1             package Lab::Moose::Instrument::RS_FSV;
2             $Lab::Moose::Instrument::RS_FSV::VERSION = '3.900';
3             #ABSTRACT: Rohde & Schwarz FSV Signal and Spectrum Analyzer
4              
5 2     2   2494 use v5.20;
  2         9  
6              
7              
8 2     2   18 use PDL::Core qw/pdl cat/;
  2         5  
  2         24  
9              
10 2     2   238 use Moose;
  2         5  
  2         17  
11 2     2   14535 use Moose::Util::TypeConstraints;
  2         6  
  2         19  
12 2     2   4564 use MooseX::Params::Validate;
  2         7  
  2         19  
13 2     2   924 use Lab::Moose::Instrument qw/timeout_param precision_param/;
  2         6  
  2         150  
14 2     2   15 use Carp;
  2         5  
  2         125  
15 2     2   12 use namespace::autoclean;
  2         6  
  2         19  
16              
17             extends 'Lab::Moose::Instrument';
18              
19             with qw(
20             Lab::Moose::Instrument::Common
21              
22             Lab::Moose::Instrument::SCPI::Format
23              
24             Lab::Moose::Instrument::SCPI::Sense::Bandwidth
25             Lab::Moose::Instrument::SCPI::Sense::Frequency
26             Lab::Moose::Instrument::SCPI::Sense::Sweep
27              
28             Lab::Moose::Instrument::SCPI::Initiate
29              
30             Lab::Moose::Instrument::SCPIBlock
31              
32             );
33              
34             sub BUILD {
35 1     1 0 4 my $self = shift;
36 1         10 $self->clear();
37 1         7 $self->cls();
38             }
39              
40              
41              
42             sub get_spectrum {
43 3     3 1 5987 my ( $self, %args ) = validated_hash(
44             \@_,
45             timeout_param(),
46             precision_param(),
47             trace => { isa => 'Int', default => 1 },
48             );
49              
50 3         5590 my $precision = delete $args{precision};
51              
52 3         10 my $trace = delete $args{trace};
53              
54 3 50 33     21 if ( $trace < 1 || $trace > 6 ) {
55 0         0 croak "trace has to be in (1..6)";
56             }
57              
58 3         16 my $freq_array = $self->sense_frequency_linear_array();
59              
60             # Ensure single sweep mode.
61 3 100       13 if ( $self->cached_initiate_continuous() ) {
62 1         5 $self->initiate_continuous( value => 0 );
63             }
64              
65             # Ensure correct data format
66 3         16 $self->set_data_format_precision( precision => $precision );
67              
68             # Get data.
69 3         5 my $num_points = @{$freq_array};
  3         7  
70 3         11 $args{read_length} = $self->block_length(
71             precision => $precision,
72             num_points => $num_points
73             );
74 3         15 $self->initiate_immediate();
75 3         17 $self->wai();
76 3         27 my $binary = $self->binary_query(
77             command => "TRAC? TRACE$trace",
78             %args
79             );
80 3         20 my $points_ref = pdl $self->block_to_array(
81             binary => $binary,
82             precision => $precision
83             );
84              
85 3         276 return cat( ( pdl $freq_array), $points_ref );
86              
87             }
88              
89              
90             #
91             #
92             # Stuff from legacy Lab::Instrument::SpectrumSCPI
93             # Needs cleanup and docs.
94             #
95             #
96              
97             # sub selftest {
98             # my $self = shift;
99             # return $self->query("*TST");
100             # }
101              
102             # sub reset {
103             # my $self = shift;
104             # $self->write("*RST");
105             # }
106              
107             # sub set_power_unit {
108             # my $self = shift;
109             # my $unit = shift || "DBM"; #DBM, W
110             # $self->write("UNIT:POW $unit");
111             # }
112              
113             # sub set_frequency {
114             # my $self = shift;
115             # my $freq = shift || "DEF"; #Hz
116             # $self->write("FREQ:CENT $freq");
117             # }
118              
119             # sub set_span {
120             # my $self = shift;
121             # my $span = shift || "DEF"; #Hz
122             # $self->write("FREQ:SPAN $span");
123             # }
124              
125             # sub set_bandwidth {
126             # my $self = shift;
127             # my $bw = shift || "DEF"; #Hz
128             # $self->write("BAND:RES $bw");
129             # }
130              
131             # sub set_sweep_time {
132             # my $self = shift;
133             # my $time = shift || "DEF"; #Hz
134             # $self->write("SWE:Time $time");
135             # }
136              
137             # sub set_continous {
138             # my $self = shift;
139             # my $cont = shift || "ON"; #ON, OFF
140             # $self->write("INIT:CONT $cont");
141             # }
142              
143             # sub auto_adjust_level {
144             # my $self = shift;
145             # $self->write(command => "SENSe:ADJ:LEVel");
146             # }
147              
148             # #NOTE: In auto attenation mode this function also switches attenuators.
149             # sub set_reference_level {
150             # my $self = shift;
151             # my $level = shift || "0"; #in dBm
152             # $self->write(command => "DISP:TRACe:Y:RLEVel $level");
153             # }
154              
155             # sub set_preamp {
156             # my $self = shift;
157             # my $state = shift || "OFF"; #ON, OFF
158             # $self->write(command => "INPut:GAIN:STATe $state");
159             # }
160              
161             # sub set_marker_auto_peak {
162             # my $self = shift;
163             # my $state = shift || "ON";
164             # my $marker = shift || 1;
165             # $self->write(command => "CALC:MARKer$marker:MAX:AUTO $state");
166             # }
167              
168             # sub get_marker_frequency {
169             # my $self = shift;
170             # my $marker = shift || 1;
171             # return $self->query(command => "CALC:MARK:X?");
172             # }
173              
174             # sub get_marker_level {
175             # my $self = shift;
176             # my $marker = shift || 1;
177             # return $self->query(command => "CALC:MARK:Y?");
178             # }
179              
180             # sub set_time_domain {
181             # my $self = shift;
182             # my $freq = shift;
183             # my $bw = shift;
184             # $self->set_continous("OFF");
185             # $self->set_frequency($freq);
186             # $self->set_span("0 Hz");
187             # $self->set_bandwidth($bw);
188             # $self->set_sweep_time("2000 US"); #TODO
189             # }
190              
191             # sub single_sweep {
192             # my $self = shift;
193             # $self->write(command => "INIT;*WAI");
194             # }
195              
196             # sub read_rms {
197             # my $self = shift;
198             # $self->single_sweep();
199             # $self->write(command => "CALC:MARK:FUNC:SUMM:RMS ON");
200             # return $self->query(command => ":CALC:MARK:FUNC:SUMM:RMS:RES?");
201             # }
202              
203             # sub read {
204             # my $self = shift;
205              
206             # #TODO: Check other modes
207             # return $self->query(command => "READ?");
208              
209             # }
210              
211             # sub get_error {
212             # my $self = shift;
213             # my $current_error = "";
214             # my $all_errors = "";
215             # my $max_errors = 5;
216             # while ( $max_errors-- ) {
217             # $current_error = $self->query(command => 'SYST:ERR?');
218             # if ( $current_error eq "" ) {
219             # $all_errors .= "Could not read error message!\n";
220             # last;
221             # }
222             # if ( $current_error =~ m/^\+?0,/ ) { last; }
223             # $all_errors .= $current_error . "\n";
224             # }
225             # if ( !$max_errors ) { $all_errors .= "Maximum Error count reached!\n"; }
226             # $self->write(command => "*CLS"); #Clear errors
227             # chomp($all_errors);
228             # return $all_errors;
229             # }
230              
231             __PACKAGE__->meta()->make_immutable();
232              
233             1;
234              
235             __END__
236              
237             =pod
238              
239             =encoding UTF-8
240              
241             =head1 NAME
242              
243             Lab::Moose::Instrument::RS_FSV - Rohde & Schwarz FSV Signal and Spectrum Analyzer
244              
245             =head1 VERSION
246              
247             version 3.900
248              
249             =head1 SYNOPSIS
250              
251             my $data = $fsv->get_spectrum(timeout => 10);
252              
253             =head1 METHODS
254              
255             This driver implements the following high-level method:
256              
257             =head2 get_spectrum
258              
259             $data = $fsv->get_spectrum(timeout => 10, trace => 2, precision => 'double');
260              
261             Perform a single sweep and return the resulting spectrum as a 2D PDL:
262              
263             [
264             [freq1, freq2, freq3, ..., freqN],
265             [power1, power2, power3, ..., powerN],
266             ]
267              
268             I.e. the first dimension runs over the sweep points.
269              
270             This method accepts a hash with the following options:
271              
272             =over
273              
274             =item B<timeout>
275              
276             timeout for the sweep operation. If this is not given, use the connection's
277             default timeout.
278              
279             =item B<trace>
280              
281             number of the trace (1..6). Defaults to 1.
282              
283             =item B<precision>
284              
285             floating point type. Has to be 'single' or 'double'. Defaults to 'single'.
286              
287             =back
288              
289             =head2 Consumed Roles
290              
291             This driver consumes the following roles:
292              
293             =over
294              
295             =item L<Lab::Moose::Instrument::Common>
296              
297             =item L<Lab::Moose::Instrument::SCPI::Format>
298              
299             =item L<Lab::Moose::Instrument::SCPI::Sense::Bandwidth>
300              
301             =item L<Lab::Moose::Instrument::SCPI::Sense::Frequency>
302              
303             =item L<Lab::Moose::Instrument::SCPI::Sense::Sweep>
304              
305             =item L<Lab::Moose::Instrument::SCPI::Initiate>
306              
307             =item L<Lab::Moose::Instrument::SCPIBlock>
308              
309             =back
310              
311             =head1 COPYRIGHT AND LICENSE
312              
313             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
314              
315             Copyright 2016 Simon Reinhardt
316             2017 Andreas K. Huettel, Simon Reinhardt
317             2020 Andreas K. Huettel
318              
319              
320             This is free software; you can redistribute it and/or modify it under
321             the same terms as the Perl 5 programming language system itself.
322              
323             =cut