File Coverage

blib/lib/Sim/OPT/Parcoord3d.pm
Criterion Covered Total %
statement 77 347 22.1
branch 0 50 0.0
condition n/a
subroutine 26 37 70.2
pod 0 11 0.0
total 103 445 23.1


line stmt bran cond sub pod time code
1             package Sim::OPT::Parcoord3d;
2             # Copyright (C) 2015 by Gian Luca Brunetti and Politecnico di Milano.
3             # This is Sim::OPT::Parcoord3d, a program that can receive as input the data for a bi-dimensional parallel coordinate plot in cvs format to produce as output an Autolisp file that can be used from Autocad or Intellicad-based 3D CAD programs to obtain 3D parallel coordinate plots.
4             # This is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
5            
6 1     1   14 use v5.14;
  1         4  
7             # use v5.20;
8 1     1   5 use Exporter;
  1         2  
  1         46  
9 1     1   4 use parent 'Exporter'; # imports and subclasses Exporter
  1         1  
  1         6  
10            
11 1     1   48 use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
  1         1  
  1         63  
12 1     1   4 use Math::Trig;
  1         2  
  1         148  
13 1     1   4 use Math::Round;
  1         1  
  1         47  
14 1     1   3 use Math::Round 'nlowmult';
  1         1  
  1         57  
15 1     1   4 use List::Util qw[ min max reduce shuffle];
  1         1  
  1         73  
16 1     1   4 use List::MoreUtils qw(uniq);
  1         2  
  1         6  
17 1     1   345 use List::AllUtils qw(sum);
  1         2  
  1         40  
18 1     1   3 use Statistics::Basic qw(:all);
  1         2  
  1         11  
19 1     1   408 use IO::Tee;
  1         1  
  1         30  
20 1     1   4 use Set::Intersection;
  1         1  
  1         40  
21 1     1   3 use List::Compare;
  1         2  
  1         15  
22 1     1   4 use Data::Dumper;
  1         1  
  1         42  
23             #$Data::Dumper::Indent = 0;
24             #$Data::Dumper::Useqq = 1;
25             #$Data::Dumper::Terse = 1;
26 1     1   3 use Data::Dump qw(dump);
  1         1  
  1         38  
27 1     1   5 use feature 'say';
  1         1  
  1         75  
28 1     1   4 no strict;
  1         1  
  1         25  
29 1     1   4 no warnings;
  1         1  
  1         44  
30            
31 1     1   6 use Sim::OPT;
  1         1  
  1         50  
32 1     1   5 use Sim::OPT::Morph;
  1         2  
  1         181  
33 1     1   4 use Sim::OPT::Sim;
  1         1  
  1         39  
34 1     1   4 use Sim::OPT::Retrieve;
  1         1  
  1         54  
35 1     1   4 use Sim::OPT::Report;
  1         1  
  1         35  
36 1     1   3 use Sim::OPT::Descend;
  1         2  
  1         33  
37 1     1   3 use Sim::OPT::Takechance;
  1         2  
  1         3275  
38            
39             our @ISA = qw(Exporter); # our @adamkISA = qw(Exporter);
40             #%EXPORT_TAGS = ( DEFAULT => [qw( &opt &prepare )]); # our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
41             #@EXPORT_OK = qw(); # our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
42            
43             @EXPORT = qw( parcoord3d ); # our @EXPORT = qw( );
44             $VERSION = '0.01';
45            
46             #########################################################################################
47             # HERE FOLLOWS THE CONTENT OF "Parcoord3d.pm", Sim::OPT::Parcoord3d
48             #########################################################################################
49            
50             sub parcoord3d
51             {
52 0 0   0 0   if ( not ( @ARGV ) )
53             {
54 0           $toshell = $main::toshell;
55             #$tee = new IO::Tee(\*STDOUT, ">>$toshell"); # GLOBAL ZZZ
56 0           say $tee "\n#Now in Sim::OPT::Takechance.\n";
57 0           $configfile = $main::configfile; #say "dump(\$configfile): " . dump($configfile);
58 0           @sweeps = @main::sweeps; #say "dump(\@sweeps): " . dump(@sweeps);
59 0           @varinumbers = @main::varinumbers; say $tee "dump(\@varinumbers): " . dump(@varinumbers);
  0            
60 0           @mediumiters = @main::mediumiters;
61 0           @rootnames = @main::rootnames; #say "dump(\@rootnames): " . dump(@rootnames);
62 0           %vals = %main::vals; #say "dump(\%vals): " . dump(%vals);
63            
64 0           $mypath = $main::mypath; #say TOSHELL "dumpINDESCEND(\$mypath): " . dump($mypath);
65 0           $exeonfiles = $main::exeonfiles; #say TOSHELL "dumpINDESCEND(\$exeonfiles): " . dump($exeonfiles);
66 0           $generatechance = $main::generatechance;
67 0           $file = $main::file;
68 0           $preventsim = $main::preventsim;
69 0           $fileconfig = $main::fileconfig; #say TOSHELL "dumpINDESCEND(\$fileconfig): " . dump($fileconfig); # NOW GLOBAL. TO MAKE IT PRIVATE, FIX PASSING OF PARAMETERS IN CONTRAINTS PROPAGATION SECONDARY SUBROUTINES
70 0           $outfile = $main::outfile;
71 0           $target = $main::target;
72            
73 0           $convertfile = $main::convertfile;
74 0           $pick = $main::pick;
75 0           $numof_pars = $main::numof_pars;
76 0           $xspacing = $main::xspacing;
77 0           $yspacing = $main::yspacing;
78 0           $zspacing = $main::zspacing;
79 0           $ob_column = $main::ob_column;
80 0           $numof_layers = $main::numof_layers;
81 0           $otherob_column = $main::otherob_column;
82 0           $cut_column = $main::cut_column;
83 0           $writefile = $main::writefile;
84 0           $writefile_pretreated = $main::writefile_pretreated;
85 0           $transitional = $main::transitional;
86 0           $newtransitional = $main::newtransitional;
87 0           $lispfile = $main::lispfile;
88 0           @layercolours = @main::layercolours;
89 0           $offset = $main::offset;
90 0           $brushspacing = $main::brushspacing;
91             }
92             else
93             {
94 0           my $file = $ARGV[0];
95 0           require $file;
96             }
97            
98 0           my $scale_xspacing = ( $numof_pars / $xspacing );
99            
100 0 0         open ( CONVERTFILE, $convertfile ) or die;
101 0           my @lines = ;
102 0           close CONVERTFILE;
103            
104 0 0         if ($pick)
105             {
106 0           $convertedfile = "$convertfile" . "filtered.csv";
107 0 0         open ( CONVERTEDFILE, ">$convertedfile" ) or die;
108 0           my $countline = 0;
109 0           while ( $countline < $pick )
110             {
111 0           print CONVERTEDFILE "$lines[$countline]";
112 0           $countline++;
113             }
114            
115 0           $countline = ($#lines - $pick) ;
116 0           while ( $countline < $#lines )
117             {
118 0           print CONVERTEDFILE "$lines[$countline]";
119 0           $countline++;
120             }
121 0           close CONVERTEDFILE;
122            
123 0           open (CONVERTEDFILE, "$convertedfile" );
124 0           @lines = ;
125 0           close CONVERTEDFILE;
126             }
127            
128 0           my $numof_layerelts = ( scalar(@lines) / $numof_layers ); # scalar(@lines = num of trials
129            
130 0           my @newdata;
131             sub makedata
132             {
133 0     0 0   my $swap = shift; my @lines = @$swap;
  0            
134            
135 0           my $countline = 0;
136 0           foreach my $line (@lines)
137             {
138 0           my @linedata;
139 0           chomp($line);
140 0           my @rowelts = split(/,/ , $line);
141 0           my $ob_fun;
142 0 0         if ($ob_column)
143             {
144 0           $ob_fun = $rowelts[$ob_column];
145             }
146             else
147             {
148 0           $ob_fun = $rowelts[$#rowelts];
149             }
150            
151 0           my $otherob_fun = $rowelts[$otherob_column];
152 0 0         if ( $otherob_fun =~ /-/ )
153             {
154 0           my @thesedata = split( /-/ , $otherob_fun );
155 0           $otherob_fun = $thesedata[1];
156             }
157            
158 0           my $countvar = 0;
159 0           foreach my $rowelt (@rowelts)
160             {
161 0 0         if ( $countvar < $numof_pars )
162             {
163 0 0         if ( $rowelt =~ /-/ )
164             {
165 0           my @vardata = split( /-/ , $rowelt );
166             #say "VARDATA: " . Dumper(@vardata);
167 0           push ( @linedata, [ @vardata ] );
168             }
169             else
170             {
171 0           push ( @linedata, [ $countvar, $rowelt ] );
172             }
173 0           $countvar++;
174             }
175             }
176 0           push ( @newdata, [ @linedata, $otherob_fun, $ob_fun ] );
177 0           $countline++;
178             }
179             }
180 0           makedata(\@lines);
181            
182 0           my ( @pars, @obfun, @otherobfun, $maxobfun, $minobfun, @maxpars, @minpars, $othermaxobfun, $otherminobfun, $countmaxobfun, $countminobfun, $countmaxotherobfun, $countminotherobfun ) ;
183             sub makestats
184 0           {
185 0     0 0   my $swap = shift; my @newdata = @$swap;
  0            
186 0           foreach my $line (@newdata)
187             {
188 0           chomp($line);
189 0           my @elts = @{$line};
  0            
190            
191 0           my $elm1 = pop(@elts);
192 0           push ( @obfun, $elm1 );
193 0           my $elm2 = pop(@elts);
194 0           push ( @otherobfun, $elm2 );
195            
196 0           my $count = 0;
197 0           foreach my $elt (@elts)
198             {
199 0           my @pair = @{$elt};
  0            
200 0           my $value = $pair[1];
201 0           push ( @{$pars[$count]}, $value );
  0            
202 0           $count++;
203             }
204             }
205            
206 0           $maxobfun = max(@obfun);
207 0           $minobfun = min(@obfun);
208 0           $maxotherobfun = max(@otherobfun);
209 0           $minotherobfun = min(@otherobfun);
210            
211 0           $countel = 0;
212 0           foreach my $e (@obfun)
213             {
214 0 0         if ($e eq $maxobfun )
215             {
216 0           $countmaxobfun = $countel;
217             }
218 0 0         if ($e eq $minobfun )
219             {
220 0           $countminobfun = $countel;
221             }
222 0           $countel++;
223             }
224            
225 0           my $countel2 = 0;
226 0           foreach my $e (@otherobfun)
227             {
228 0 0         if ($e eq $maxotherobfun )
229             {
230 0           $countmaxotherobfun = $countel2;
231             }
232 0 0         if ($e eq $minotherobfun )
233             {
234 0           $countminotherobfun = $countel2;
235             }
236 0           $countel2++;
237             }
238            
239             sub printpar
240             {
241 0     0 0   foreach my $par (@pars)
242             {
243 0           print WRITEFILE "PAR: @$par \n";
244             }
245             }
246             }
247 0           makestats(\@newdata);
248            
249             sub writeminmaxpars
250             {
251 0     0 0   my $swap = shift; my @pars = @$swap;
  0            
252 0           my $countpar = 0;
253 0           foreach my $par (@pars)
254             {
255 0           my @elts = @$par;
256 0           push ( @maxpars, max(@elts) );
257 0           push ( @minpars, min(@elts) );
258 0           $countpar++;
259             }
260             }
261 0           writeminmaxpars(\@pars);
262            
263 0           my ( @plotdata, @newplotdata, @newnewdata );
264             sub plotdata
265             {
266 0     0 0   my $case_per_layer = ( scalar(@newdata) / $numof_layers );
267 0           $countcase = 0;
268 0           foreach my $el ( @{$pars[0]} )
  0            
269             {
270 0           my @provbowl;
271 0           my $scaled_zvalue = ( ( $newdata[$countcase][($#{$newdata[$countcase]}-1)] - $minotherobfun ) / ( $maxotherobfun - $minotherobfun ) );
  0            
272 0           my $countvar = 0;
273 0           while ($countvar < $numof_pars)
274             {
275 0           my $layer_num = ( int( $countcase / $case_per_layer ) + 1) ;
276 0           my $scaled_xvalue = ( $countvar / $scale_xspacing );
277 0           my $scaled_yvalue = ( ( $pars[$countvar][$countcase] - $minpars[$countvar] ) / ( $maxpars[$countvar] - $minpars[$countvar] ) );
278 0           $scaled_yvalue = ($scaled_yvalue * $yspacing);
279 0           $scaled_zvalue = ($scaled_zvalue * $zspacing);
280 0 0         if ($otherob_column)
281             {
282 0           push (@provbowl, [ $scaled_xvalue, $scaled_yvalue, $scaled_zvalue, $layer_num ] );
283             }
284             else
285             {
286 0           push (@provbowl, [ $scaled_xvalue, $scaled_yvalue, 0, $layer_num ] );
287             }
288 0           $countvar++;
289             }
290 0           push (@plotdata, [ @provbowl ]);
291 0           $countcase++;
292             }
293             }
294 0           plotdata;
295            
296             sub cutcoordinates
297             {
298 0     0 0   foreach (@plotdata)
299             {
300 0           splice( @{$_}, $cut_column, 1);
  0            
301             }
302             }
303 0 0         if ($cut_column)
304             {
305 0           cutcoordinates; # CUTS SPECIFIED COORDINATES
306             }
307            
308             sub printplotdata_pretreated
309             {
310 0 0   0 0   open (WRITEFILE_PRETREATED, ">$writefile_pretreated") or die;
311 0           print WRITEFILE_PRETREATED dump(@plotdata); #CONTROL!!!
312 0           close WRITEFILE_PREATREATED;
313             }
314 0           printplotdata_pretreated;
315            
316             sub solidify
317 0     0 0   {print "BEGUN\n";
318 0           my $swap = shift; my @plotdata = @$swap;
  0            
319 0 0         open (WRITEFILE, ">$writefile") or die;
320 0           my $countgroup = 0;
321 0           foreach my $e (@plotdata)
322             {#print "INLEVEL2\n";
323 0           my @elts = @{$e};
  0            
324 0           my @newnewbag;
325 0           my $counter = 0;
326 0           foreach my $elm (@elts)
327             {#print "INLEVEL3\n";
328 0           my @elms = @{$elm};
  0            
329 0           my @cutelms = @elms[0..2]; # PUT ..2 IF ALSO THE THIRD AXIS HAS TO BE CHECKED FOR NON-REPETITIONS, PUT 1 OTHERWISE.
330 0           my $counthit = -1;
331 0           foreach my $el (@plotdata)
332             {#print "INLEVEL4\n";
333 0           my @els = @{$el};
  0            
334 0           foreach my $elem (@els)
335             {#print "INLEVEL5,6\n";
336 0           my @elems = @{$elem};
  0            
337 0           my @cutelems = @elems[0..2]; # PUT ..2 IF ALSO THE THIRD AXIS HAS TO BE CHECKED FOR NON-REPETITIONS, PUT 1 OTHERWISE.
338 0 0         if (@cutelms ~~ @cutelems)
339             {#print "INLEVEL7\n";
340             #print "CUTELMS: " . dump(@cutelms) . "\nCUTELEMS: " . dump(@cutelems) . "\n";
341 0           $counthit++;
342 0           print "COUNTGROUP: $countgroup, HIT! $counthit\n";
343            
344 0 0         if ($counthit > 0)
345             {
346 0           print "COUNTHITNOW: $counthit\n";
347 0 0         if ( $counthit % 2 == 1) # odd
348             {
349 0           $elms[0] = ( $elms[0] - ( $brushspacing * $counthit ) );
350             }
351             else
352             {
353 0           $elms[0] = ( $elms[0] + ( $brushspacing * $counthit ) );
354             }
355 0           push ( @newnewbag, [ nlowmult(0.0001, $elms[0]), nlowmult(0.0001, $elms[1]), nlowmult(0.0001, $elms[2]), nlowmult(0.0001, $elms[3]) ]);
356             }
357             else
358             {
359 0           push(@newnewbag, [ nlowmult(0.0001, $elms[0]), nlowmult(0.0001, $elms[1]), nlowmult(0.0001, $elms[2]), nlowmult(0.0001, $elms[3]) ]);
360             }
361             }
362             }
363             }
364            
365 0           $counter++
366             }
367 0           push( @newplotdata, [ @newnewbag ] );
368 0           $countgroup++;
369             }
370 0           print WRITEFILE dump(@newplotdata);
371 0           close WRITEFILE;
372             }
373 0           solidify(\@plotdata);
374            
375            
376             #my @plotdata = eval `cat $writefile`;
377            
378             sub prepare
379             {
380 0 0   0 0   open( TRANSITIONAL, ">$transitional" ) or die;
381 0           my $countgroup = 0;
382 0           foreach my $group (@newplotdata)
383             {
384 0           my @elts = @{$group};
  0            
385 0           my $countpar = 0;
386 0           my ( @newplotdatabottom, @newplotdatafront, @newplotdataback, @newplotdataright, @newplotdataleft );
387 0           foreach my $elt (@elts)
388             {
389 0           my @coords = @{$elt};
  0            
390 0           my @nextcoords = @{$elts[$countpar+1]};
  0            
391             #print "COORDS: " . dump(@coords);
392             #print "NEXTCOORDS: " . dump(@nextcoords);
393 0           my @newcoords;
394 0           push( @newcoords, [ @coords ] );
395 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , $coords[2], $coords[3] ] );
396 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
397 0           push( @newcoords, [ $coords[0], $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
398 0           push( @newplotdatabottom, [ @newcoords ] );
399             #print "DONE1 BOTTOM COUNTGROUP $countgroup COUNTPAR $countpar\n";
400            
401 0           my @newcoords;
402 0 0         unless ($countpar == $#elts)
403             {
404 0           push( @newcoords, [ @coords ] );
405 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , $coords[2], $coords[3] ] );
406 0           push( @newcoords, [ ($nextcoords[0] - ($yspacing * $offset ) ) , $nextcoords[1] , $nextcoords[2], $nextcoords[3] ] );
407 0           push( @newcoords, [ @nextcoords] );
408 0           push( @newplotdatafront, [ @newcoords ] );
409             }
410             #print "DONE2 FRONT COUNTPAR $countpar\n";
411            
412 0           my @newcoords;
413 0 0         unless ($countpar == $#elts)
414             {
415 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , $coords[2], $coords[3] ] );
416 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
417 0           push( @newcoords, [ ($nextcoords[0] - ($yspacing * $offset ) ) , $nextcoords[1] , ( $nextcoords[2] - ($yspacing * $offset ) ) , $nextcoords[3] ] );
418 0           push( @newcoords, [ ($nextcoords[0] - ($yspacing * $offset ) ) , $nextcoords[1] , $nextcoords[2], $nextcoords[3] ] );
419 0           push( @newplotdataleft, [ @newcoords ] );
420             }
421             #print "DONE3 LEFT COUNTPAR $countpar\n";
422            
423 0           my @newcoords;
424 0 0         unless ($countpar == $#elts)
425             {
426 0           push( @newcoords, [ ($coords[0] - ($yspacing * $offset ) ) , $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
427 0           push( @newcoords, [ $coords[0], $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
428 0           push( @newcoords, [ $nextcoords[0], $nextcoords[1] , ( $nextcoords[2] - ($yspacing * $offset ) ) , $nextcoords[3] ] );
429 0           push( @newcoords, [ ($nextcoords[0] - ($yspacing * $offset ) ) , $nextcoords[1] , ( $nextcoords[2] - ($yspacing * $offset ) ) , $nextcoords[3] ] );
430 0           push( @newplotdataback, [ @newcoords ] );
431             }
432             #print "DONE4 BACK COUNTPAR $countpar\n";
433            
434 0           my @newcoords;
435 0 0         unless ($countpar == $#elts)
436             {
437 0           push( @newcoords, [ $coords[0], $coords[1] , ( $coords[2] - ($yspacing * $offset ) ) , $coords[3] ] );
438 0           push( @newcoords, [ @coords ] );
439 0           push( @newcoords, [ @nextcoords ] );
440 0           push( @newcoords, [ $nextcoords[0], $nextcoords[1] , ( $nextcoords[2] - ($yspacing * $offset ) ) , $nextcoords[3] ] );
441 0           push( @newplotdataright, [ @newcoords ] );
442             }
443             #print "DONE5 RIGHT COUNTPAR $countpar\n";
444             # print "COUNTPAR: $countpar\n";
445 0           $countpar++;
446             }
447            
448 0 0         if (@newplotdatafront)
449             {
450 0           push(@newnewdata, @newplotdatabottom , @newplotdatafront, @newplotdataleft, @newplotdataback, @newplotdataright );
451             }
452             else
453             {
454 0           push(@newnewdata, @newplotdatabottom );
455             }
456            
457             # print "COUNTGROUP: $countgroup\n";
458 0           $countgroup++;
459             }
460 0           print TRANSITIONAL dump(@newnewdata);
461 0           close TRANSITIONAL;
462             }
463 0           prepare;
464            
465            
466             sub writelisp
467             {
468 0     0 0   open(LISPFILE, ">$lispfile");
469 0           my $counter = 1;
470 0           foreach my $colour (@layercolours)
471             {
472 0           print LISPFILE "\( command \"layer\" \"m\" \"$counter\" \"c\" \"$colour\" \"\" \"\" \)\n";
473 0           $counter++;
474             }
475 0           foreach my $series (@newnewdata)
476             {
477 0           my @vs = @{$series};
  0            
478 0           print LISPFILE "\( command \"layer\" \"s\" \"$vs[0][3]\" \"\" \)\n";
479 0           print LISPFILE "\( command \"3dface\" \"$vs[0][0],$vs[0][2],$vs[0][1]\" \"$vs[1][0],$vs[1][2],$vs[1][1]\" \"$vs[2][0],$vs[2][2],$vs[2][1]\" \"$vs[3][0],$vs[3][2],$vs[3][1]\" \"\" \)\n";
480             }
481 0           close LISPFILE;
482             }
483 0           writelisp;
484             }
485            
486             1;
487            
488            
489             __END__