use strict; use warnings; use Math::FFT; use Tk; use Tk::Canvas; package ATSComments80_s; sub new { my ($class, $fileHandle) = @_; my $self = bless {fh => $fileHandle}, $class; $self->load(); return $self; } sub load { my ($self) = @_; read $self->{fh}, $self->{achClient}, 16; read $self->{fh}, $self->{achContractor}, 16; read $self->{fh}, $self->{achArea}, 16; read $self->{fh}, $self->{achSurveyID}, 16; read $self->{fh}, $self->{achOperator}, 16; read $self->{fh}, $self->{achReserved}, 112; read $self->{fh}, $self->{achXmlHeader}, 64; read $self->{fh}, $self->{achComments}, 512; } package ATSHeader80_s; sub new { my ($class, $fileHandle) = @_; my $self = bless {fh => $fileHandle}, $class; $self->load(); return $self; } sub load { my ($self) = @_; read $self->{fh}, $self->{siHeaderLength}, 2; $self->{siHeaderLength} = unpack 's<', $self->{siHeaderLength}; ...; read $self->{fh}, $self->{abyADBBoardType}, 4; $self->{tscComment} = ATSComments80_s->new($self->{fh}); } package main; my $filePath = $ARGV[0] // "testData.ats"; open my $fh, '<:raw', $filePath or die "Can't open $filePath: $!"; my $header = ATSHeader80_s->new($fh); my $itemCount = 0; my @data; while ($itemCount++ < 1024 && read $fh, my ($value), 4) { $value = unpack 'l<', $value; push @data, $value; } my $fft = Math::FFT->new(\@data); my $mw = MainWindow->new (-title => "Magnetometer Plotter"); my $canvas = $mw->Canvas (-height => 700, -width => 1024)->pack (); my $spectrum = $fft->spctrm; # Remove DC signal component shift @$spectrum; $spectrum = NormData($spectrum, 680); $canvas->createLine( (map {2 + 2 * $_, $spectrum->[$_]} 0 .. $#$spectrum), -fill => 'blue' ); $mw->MainLoop (); sub NormData { my ($data, $span) = @_; my $min; my $max; for my $datum (@$data) { $min //= $datum; $max //= $datum; $min = $datum if $min > $datum; $max = $datum if $max < $datum; } my $scale = $span / ($max - $min); $_ = $span - ($_ - $min) * $scale + 10 for @$data; return $data; }