#!/usr/local/bin/perl -w # # Reads 2 tkmap format linear maps and compares them. # Optional 3rd file name is to save postscript output. # # Copyright (C) 1996 Humberto Ortiz Zuazaga and Rosemarie Plaetke. # # This program 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; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # See the file licence.html for a copy of the GNU GPL use Tk; use strict; use English; ### Edit these global variables. my $height = 600; my $width = 600; my ($topm, $botm, $leftm, $rightm) = (25, 25, 25, 25); my $labwidth = 175; my $mapskip = 50; my $mapwidth = 10; my $distoffset = 10; my $oddsleft = $leftm + $labwidth - 50; my $oddsright = $width - ($rightm + $labwidth) + 50; my $labelfont = '-adobe-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*'; my $distfont = '-adobe-helvetica-medium-r-normal-*-*-80-*-*-*-*-*-*'; my $units = "cM"; ## ## Stop editing. ## # If you give 3 files, save output to third. my $print = 0; $print = $ARGV[2] if $ARGV[2]; my (@map1, @map2); @map1 = readmap($ARGV[0]); @map2 = readmap($ARGV[1]); my $main = new MainWindow(); my $c = $main->Canvas(-height => $height, -width => $width); $c->pack; # draw the maps #drawmaps($c, \%map1, \%map2); my $m; my $ppu1 = ($height - $topm - $botm) / $map1[$#map1]{'pos'}; my $ppu2 = ($height - $topm - $botm) / $map2[$#map2]{'pos'}; $ppu1 = $ppu2 if $ppu1 > $ppu2; $ppu2 = $ppu1 if $ppu1 < $ppu2; my $skip1 = ($ppu1 * $map1[$#map1]{'pos'}) / $#map1; my $skip2 = ($ppu2 * $map2[$#map2]{'pos'}) / $#map2; my $i; my (%names1, %names2); # Draw map1 axis. $c->create('line', $leftm + $labwidth + $mapskip + $mapwidth / 2, $topm, $leftm + $labwidth + $mapskip + $mapwidth / 2, $topm + $map1[$#map1]{'pos'} * $ppu1, -width => 2); # Map length $c->create('text', $leftm + $labwidth + $mapskip + $mapwidth / 2 + 10, $topm + $map1[$#map1]{'pos'} * $ppu1 + 10, -text => int((0.005 + $map1[$#map1]{'pos'}) * 100) . " $units", -font => $labelfont); for ($i = 0; $i < @map1; $i++) { next if $map1[$i]{'name'} eq 'ThEmApEnD'; # Marker names $c->create('text', $leftm + $labwidth, $topm + $i * $skip1, -text => $map1[$i]{'name'}, -anchor => 'e', -font => $labelfont); # Marker odds if ($map1[$i]{'odds'}) { $c->create('text', $oddsleft, $topm + $i * $skip1 + $skip1 / 2, -text => $map1[$i]{'odds'}, -anchor => 'e', -font => $labelfont); $c->create('arc', $oddsleft + 5, $topm + $i * $skip1, $oddsleft + 15, $topm + $i * $skip1 + $skip1, -extent => 180, -start => 90, -style => 'arc'); } # Intermarker distances $c->create('text', $leftm + $labwidth + $distoffset, $topm + $i * $skip1 + $skip1 / 2, -text => int ((0.005 + $map1[$i]{'dist'}) * 100), -anchor => 'e', -font => $distfont) if defined $map1[$i]{'dist'}; # Hash the locations of the markers $names1{$map1[$i]{'name'}} = $map1[$i]{'pos'}; # Connector $c->create('line', $leftm + $labwidth, $topm + $i * $skip1, $leftm + $labwidth + $distoffset, $topm + $i * $skip1, $leftm + $labwidth + $mapskip, $topm + $map1[$i]{'pos'} * $ppu1); # Tickmark $c->create('line', $leftm + $labwidth + $mapskip, $topm + $map1[$i]{'pos'} * $ppu1, $leftm + $labwidth + $mapskip + $mapwidth, $topm + $map1[$i]{'pos'} * $ppu1, -width => 2); } # Draw map2 axis. $c->create('line', $width - ($rightm + $labwidth + $mapskip + $mapwidth / 2), $topm, $width - ($rightm + $labwidth + $mapskip + $mapwidth / 2), $topm + $map2[$#map2]{'pos'} * $ppu1, -width => 2); # Map length $c->create('text', $width - ($rightm + $labwidth + $mapskip + $mapwidth / 2 + 10), $topm + $map2[$#map2]{'pos'} * $ppu2 + 10, -text => int((0.005 + $map2[$#map2]{'pos'}) * 100) . " $units", -font => $labelfont, -anchor => 'w'); for ($i = 0; $i < @map2; $i++) { next if $map2[$i]{'name'} eq 'ThEmApEnD'; # Marker names $c->create('text', $width - ($rightm + $labwidth), $topm + $i * $skip2, -text => $map2[$i]{'name'}, -anchor => 'w', -font => $labelfont); # Marker odds if ($map2[$i]{'odds'}) { $c->create('text', $oddsright, $topm + $i * $skip2 + $skip2 / 2, -text => $map2[$i]{'odds'}, -anchor => 'w', -font => $labelfont); $c->create('arc', $oddsright - 5, $topm + $i * $skip2, $oddsright - 15, $topm + $i * $skip2 + $skip2, -extent => -180, -start => 90, -style => 'arc'); } # Intermarker distances $c->create('text', $width - ($rightm + $labwidth + $distoffset), $topm + $i * $skip2 + $skip2 / 2, -text => int((0.005 + $map2[$i]{'dist'}) * 100), -anchor => 'w', -font => $distfont) if defined $map2[$i]{'dist'}; # Hash the locations of the markers $names2{$map2[$i]{'name'}} = $map2[$i]{'pos'}; # Connector $c->create('line', $width - ($rightm + $labwidth), $topm + $i * $skip2, $width - ($rightm + $labwidth + $distoffset), $topm + $i * $skip2, $width - ($rightm + $labwidth + $mapskip), $topm + $map2[$i]{'pos'} * $ppu2); # Tickmark $c->create('line', $width - ($rightm + $labwidth + $mapskip), $topm + $map2[$i]{'pos'} * $ppu2, $width - ($rightm + $labwidth + $mapskip + $mapwidth), $topm + $map2[$i]{'pos'} * $ppu2, -width => 2); } # connect markers foreach $m (keys %names1) { if (exists($names2{$m})) { $c->create('line', $leftm + $labwidth + $mapskip + $mapwidth + 5, $topm + $names1{$m} * $ppu1, $width - ($rightm + $labwidth + $mapskip + $mapwidth + 5), $topm + $names2{$m} * $ppu2); } } if ($print) { $c->update; $c->postscript(-file => $print, -pagewidth => "7.5i"); } MainLoop; ### sub readmap { my ($file) = @ARG; my $line; my @map; my $i = 0; my $pos = 0; my ($name, $dist, $odds); open(MAP, $file) or die "readmap: can't open $file"; while ($line = ) { # Eat comments here. $line =~ s/\w*\#.*//g; chomp $line; if ($line) { if ($line =~ m/"([^"]+)"(\s+(\S+))?(\s+(\S+))?/) { #" $name = $1; $dist = $3; $odds = $5; # if defined($5); # print "n = '$name' d = '$dist' o = '$odds'\n"; } else { ($name, $dist, $odds) = split ' ',$line, 3; } $map[$i] = {'name'=>$name, 'pos'=>$pos}; $map[$i]{'odds'} = $odds if $odds; if ((defined($dist)) and ("" ne $dist)) { $map[$i]{'dist'} = $dist; $pos += $dist; } $i++; } $map[$i] = {'name'=>'ThEmApEnD', 'dist'=>$dist, 'pos'=>$pos} if (defined($dist) and ("" ne $dist)); } close MAP; return @map; } ### sub drawmaps { my ($w, $map1, $map2) = @ARG; # use $w->cget() to get width and height. }