File Coverage

blib/lib/Chart/Graph/Xrt3d.pm
Criterion Covered Total %
statement 26 171 15.2
branch 2 90 2.2
condition 0 12 0.0
subroutine 7 7 100.0
pod 0 1 0.0
total 35 281 12.4


line stmt bran cond sub pod time code
1             ## Xrt3d.pm is a sub-module of Graph.pm. It has all the subroutines
2             ## needed for the Xrt3d part of the package.
3             ##
4             ## $Id: Xrt3d.pm,v 1.30 2006/06/07 21:09:33 emile Exp $ $Name: $
5             ##
6             ## This software product is developed by Michael Young and David Moore,
7             ## and copyrighted(C) 1998 by the University of California, San Diego
8             ## (UCSD), with all rights reserved. UCSD administers the CAIDA grant,
9             ## NCR-9711092, under which part of this code was developed.
10             ##
11             ## There is no charge for this software. You can redistribute it and/or
12             ## modify it under the terms of the GNU General Public License, v. 2 dated
13             ## June 1991 which is incorporated by reference herein. This software is
14             ## distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY
15             ## OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not
16             ## infringe on any third party's intellectual property rights.
17             ##
18             ## You should have received a copy of the GNU GPL along with this program.
19             ##
20             ##
21             ## IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
22             ## PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
23             ## DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
24             ## SOFTWARE, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF
25             ## THE POSSIBILITY OF SUCH DAMAGE.
26             ##
27             ## THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND THE
28             ## UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
29             ## SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. THE UNIVERSITY
30             ## OF CALIFORNIA MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES
31             ## OF ANY KIND, EITHER IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED
32             ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
33             ## PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE
34             ## ANY PATENT, TRADEMARK OR OTHER RIGHTS.
35             ##
36             ##
37             ## Contact: graph-dev@caida.org
38             ##
39             ##
40             package Chart::Graph::Xrt3d;
41 4     4   29 use Exporter ();
  4         9  
  4         257  
42              
43             @ISA = qw(Exporter);
44             @EXPORT = qw();
45             @EXPORT_OK = qw(&xrt3d);
46              
47 4     4   30 use FileHandle; # to create generic filehandles
  4         7  
  4         41  
48 4     4   1990 use Carp; # for carp() and croak()
  4         10  
  4         366  
49 4     4   34 use Chart::Graph::Utils qw(:UTILS); # get global subs and variables
  4         6  
  4         1066  
50 4     4   23 use Chart::Graph::XrtUtils qw(:UTILS);
  4         8  
  4         2677  
51              
52             $cvs_Id = '$Id: Xrt3d.pm,v 1.30 2006/06/07 21:09:33 emile Exp $';
53             $cvs_Author = '$Author: emile $';
54             $cvs_Name = '$Name: $';
55             $cvs_Revision = '$Revision: 1.30 $';
56              
57             $VERSION = 3.2;
58              
59 4     4   27 use strict;
  4         6  
  4         8393  
60              
61             #
62             # xrt graphing package
63             #
64              
65              
66             my %def_xrt_global_opts; # xrt specific globals
67              
68             %def_xrt_global_opts = (
69             "output file" => "untitled-xrt3d.gif",
70             "output type" => "gif",
71             "x-axis title" => "x-axis",
72             "y-axis title" => "y-axis",
73             "z-axis title" => "z-axis",
74             "x-min" => "0",
75             "y-min" => "0",
76             "x-step" => "1",
77             "y-step" => "1",
78             "x-ticks" => undef,
79             "y-ticks" => undef,
80             "header" => ["header"],
81             "footer" => ["footer"],
82             );
83             #
84             #
85             # Subroutine: xrt()
86             #
87             # Description: this is the main function you will be calling from
88             # our scripts. please see
89             # www.caida.org/Tools/Graph/ for a full description
90             # and how-to of this subroutine
91             #
92              
93             sub xrt3d {
94 4     4 0 219 my $user_global_opts_ref = shift;
95 4         7 my $data_set_ref = shift;
96 4         8 my $matrix_data_ref;
97             my $data_filename;
98 0         0 my (%global_opts);
99            
100             # variables to be written to the command file
101 0         0 my ($plot_file, $x_axis, $y_axis, $z_axis, $x_step, $y_step);
102 0         0 my ($x_min, $y_min, $x_ticks, $y_ticks, $header, $footer);
103 0         0 my ($x_cnt, $y_cnt, $hdr_cnt, $ftr_cnt);
104 0         0 my ($output_file);
105              
106 4 50       116 if (@_) {
107 0         0 carp 'Too many arguments. Usage: xrt3d(\%options, \@data_set)';
108 0         0 return 0;
109             }
110              
111 4         13 _make_tmpdir("_Xrt3d_");
112              
113             # set paths for external programs
114 4 50       15 if (not _set_xrtpaths("xrt3d")) {
115 4         15 _cleanup_tmpdir();
116 4         15 return 0;
117             }
118            
119             # check first arg for hash
120 0 0         if (ref($user_global_opts_ref) ne "HASH") {
121 0           carp "Global options must be a hash.";
122 0           _cleanup_tmpdir();
123 0           return 0;
124             }
125              
126             # call to combine user options with default options
127 0           %global_opts = _mesh_opts($user_global_opts_ref, \%def_xrt_global_opts);
128            
129             # check for values in command file
130 0           while (my ($key, $value) = each %global_opts) {
131            
132 0 0         if ($key eq "output file") {
133 0           $output_file = $value;
134 0 0         unless (defined $global_opts{"output type"}) {
135 0           carp "Must have an output type defined";
136 0           _cleanup_tmpdir();
137 0           return 0;
138             }
139             }
140            
141             # If the file is PostScript ... what XRT makes is PostScript
142 0 0 0       if ($global_opts{"output type"} eq "ps") {
    0 0        
      0        
143 0           $plot_file = _make_tmpfile("plot", "ps");
144             }
145             # For all raster formats XRT starts out with
146             # X-Windows XWD format.
147             elsif (($global_opts{"output type"} eq "gif") or
148             ($global_opts{"output type"} eq "xwd") or
149             ($global_opts{"output type"} eq "png") or
150             ($global_opts{"output type"} eq "jpg")
151             ) {
152 0           $plot_file = _make_tmpfile("plot", "xwd");
153             } else {
154             # Default is XWD
155 0           carp "Unknown output type, defaulting to xwd";
156 0           $plot_file = _make_tmpfile("plot", "xwd");
157             }
158              
159              
160 0 0         if ($key eq "x-axis title") {
161 0 0         if(defined($value)) {
162 0           $x_axis = $value;
163             }
164             }
165            
166 0 0         if ($key eq "y-axis title") {
167 0 0         if(defined($value)) {
168 0           $y_axis = $value;
169             }
170             }
171            
172 0 0         if ($key eq "z-axis title") {
173 0 0         if(defined($value)) {
174 0           $z_axis = $value;
175             }
176             }
177            
178 0 0         if ($key eq "x-min") {
179 0 0         if(defined($value)) {
180 0           $x_min = $value;
181             }
182             }
183            
184 0 0         if ($key eq "y-min") {
185 0 0         if(defined($value)) {
186 0           $y_min = $value;
187             }
188             }
189            
190 0 0         if ($key eq "x-step") {
191 0 0         if(defined($value)) {
192 0           $x_step = $value;
193             }
194             }
195            
196 0 0         if ($key eq "y-step") {
197 0 0         if(defined($value)) {
198 0           $y_step = $value;
199             }
200             }
201            
202 0 0         if ($key eq "x-ticks") {
203 0 0         if(defined($value)) {
204 0           $x_ticks = $value;
205             }
206             }
207            
208 0 0         if ($key eq "y-ticks") {
209 0 0         if(defined($value)) {
210 0           $y_ticks = $value;
211             }
212             }
213            
214 0 0         if ($key eq "header") {
215 0 0         if(defined($value)) {
216 0           $header = $value;
217             }
218             }
219            
220 0 0         if ($key eq "footer") {
221 0 0         if(defined($value)) {
222 0           $footer = $value;
223             }
224             }
225             }
226            
227              
228             # Extract options for data.
229 0           my $data_opts = shift @{$data_set_ref};
  0            
230 0           while (my ($key, $value) = each %{$data_opts}) {
  0            
231 0 0         if ($key eq "type") {
232 0 0         if ($value eq "matrix") {
    0          
233 0           $matrix_data_ref = $data_set_ref;
234             }
235             elsif ($value eq "file") {
236 0           $data_filename = pop @{$data_set_ref};
  0            
237             } else {
238 0           carp "Unsupported or unknown format for data";
239             }
240             }
241             }
242            
243             # because xrt allows multiline headers
244             # get the length of the header array
245             # each line of the header is one index
246             # in the array
247              
248 0           $hdr_cnt = $#{$global_opts{"header"}} + 1;
  0            
249 0           $ftr_cnt = $#{$global_opts{"footer"}} + 1;
  0            
250            
251              
252 0 0         if (defined($matrix_data_ref)) {
253             # get the number of columns and number of rows
254             # and verify that each row has same number of
255             # columns
256            
257 0           $x_cnt = $#{$matrix_data_ref} + 1;
  0            
258 0           my $tmp = $#{$matrix_data_ref->[0]} + 1;
  0            
259            
260 0           foreach my $i (@{$matrix_data_ref}) {
  0            
261 0 0         if ($tmp != $#{$i} + 1) {
  0            
262 0           carp "each row must have the same number of columns";
263 0           _cleanup_tmpdir();
264 0           return 0;
265             }
266             }
267            
268 0           $y_cnt = $tmp;
269            
270              
271             # verify that number of tick marks == corresponds
272             # to that of xy matrix. One tick mark for every x
273             # y.
274            
275 0 0         if (not _verify_ticks($x_cnt, $global_opts{"x-ticks"})) {
276 0           _cleanup_tmpdir();
277 0           return 0;
278             }
279            
280 0 0         if (not _verify_ticks($y_cnt, $global_opts{"y-ticks"})) {
281 0           _cleanup_tmpdir();
282 0           return 0;
283             }
284             } else {
285             # XXX
286             # Poor man's hack to compute rows and columns in data file. This will
287             # make a second pass through file, but is probably faster than doing it
288             # in Perl.
289 0           my ($lead, $words, $bytes);
290 0           ($lead, $x_cnt, $words, $bytes) = split(/\D+/, `wc $data_filename`);
291 0 0 0       if (($x_cnt > 0) and ($words > 0)) {
292 0           $x_cnt++;
293 0           $y_cnt = $words/$x_cnt;
294             } else {
295 0           $x_cnt = 0;
296 0           $y_cnt = 0;
297 0           carp "Cannot compute number of rows and/or columns in file data";
298             }
299             }
300              
301             ##
302             ## print command file using this format
303             ##
304            
305             # output.file
306             # x_min (normally 0)
307             # y_min (normally 0)
308             # x_step (normally 1)
309             # y_step (normally 1)
310             # x_cnt (number of rows of input)
311             # y_cnt (number of columns of input)
312             # data11 data12 data13 data14 .... (x by y matrix of doubles)
313             # data21 data22 data23 ....
314             # .
315             # .
316             # .
317             # datax1 datax2 ... dataxy
318             # Number of header lines (multiple header lines available)
319             # header1
320             # header2
321             # ...
322             # Number of header lines (multiple header lines available)
323             # foot1
324             # foot2
325             # ...
326             # Title of x-axis
327             # Title of y-axis
328             # Title of z-axis
329             # xlabel0 (x_cnt number of labels for ticks along x-axis)
330             # ...
331             # xlabelx
332             # ylabel0 (y_cnt number of labels for ticks along y-axis)
333             # ...
334             # ylabely
335            
336             # create command file and open file handle
337 0           my $command_file = _make_tmpfile("command");
338 0           my $handle = new FileHandle;
339 0 0         if (not $handle->open(">$command_file")) {
340 0           carp "could not open $command_file";
341 0           _cleanup_tmpdir();
342 0           return 0;
343             }
344            
345 0           print $handle "$plot_file\n";
346 0           print $handle "$x_min\n";
347 0           print $handle "$y_min\n";
348 0           print $handle "$x_step\n";
349 0           print $handle "$y_step\n";
350 0           print $handle "$x_cnt\n";
351 0           print $handle "$y_cnt\n";
352 0 0         if (defined($matrix_data_ref)) {
353 0           _print_matrix($handle, @{$matrix_data_ref});
  0            
354             } else {
355 0           _transfer_file($handle, $data_filename)
356             }
357 0           print $handle "$hdr_cnt\n";
358 0           _print_array($handle, @{$header});
  0            
359 0           print $handle "$ftr_cnt\n";
360 0           _print_array($handle, @{$footer});
  0            
361 0           print $handle "$x_axis\n";
362 0           print $handle "$y_axis\n";
363 0           print $handle "$z_axis\n";
364 0           _print_array($handle, @{$x_ticks});
  0            
365 0           _print_array($handle, @{$y_ticks});
  0            
366 0           $handle->close();
367              
368             # call xrt and convert file to gif
369 0 0         if (not _exec_xrt3d($command_file)) {
370 0           _cleanup_tmpdir();
371 0           return 0;
372             }
373 0           my $graph_format = $global_opts{"output type"};
374 0 0         if ($graph_format eq "ps") {
    0          
375 0 0         if (not _chk_status(system("cp $plot_file $output_file"))) {
376 0           _cleanup_tmpdir();
377 0           return 0;
378             }
379             } elsif ($graph_format eq "xwd") {
380 0 0         if (not _chk_status(system("cp $plot_file $output_file"))) {
381 0           _cleanup_tmpdir();
382 0           return 0;
383             }
384             } else {
385 0 0         if(not _convert_raster($graph_format, $plot_file, $output_file)) {
386 0           _cleanup_tmpdir();
387 0           return 0;
388             }
389             }
390              
391 0           _cleanup_tmpdir();
392 0           return 1;
393             }
394            
395             1;
396              
397              
398             __END__