psdlag-agn/scripts/tophat_fft.pl

85 lines
2.1 KiB
Perl
Raw Permalink Normal View History

#!/usr/bin/env perl
use feature say;
2016-08-12 09:14:03 +00:00
use utf8;
use PDL;
use PDL::FFT;
use PDL::IO::Misc;
2016-08-14 02:45:00 +00:00
my $_2π = 2*3.1415926539;
# space parameters
2016-08-14 02:45:00 +00:00
our $xres= 0.1;
our $xmin = 0;
2016-08-14 02:45:00 +00:00
our $xmax = 2500;
our $xbins = ($xmax-$xmin)/$xres + 1;
say "Using $xbins bins";
2016-08-12 09:14:03 +00:00
# tophat parameters
2016-08-14 02:45:00 +00:00
my $μ1=7;
2016-08-12 09:14:03 +00:00
my $Δ1=5; # full width
2016-08-14 02:45:00 +00:00
my @tophat_list = ([$μ1,$Δ1],[28,8],[15,11]);
2016-08-14 02:45:00 +00:00
our $tophat_count = 0;
foreach (@tophat_list) {
2016-08-14 02:45:00 +00:00
$tophat_count++;
2016-08-14 02:45:00 +00:00
# Capture tophat into piddle
# Complex Number z(x) = u(x) + iv(x)
my $u = tophat(@$_[0],@$_[1]);
2016-08-14 02:45:00 +00:00
my $v = zeroes($u);
2016-08-14 02:45:00 +00:00
$x_coords = $u->xlinvals($xmin,$xmax);
2016-08-12 09:14:03 +00:00
2016-08-14 02:45:00 +00:00
# Output x-domain tophat
wcols $x_coords,$u,"analyses/tables/tophat${tophat_count}.tab";
2016-08-12 09:14:03 +00:00
2016-08-14 02:45:00 +00:00
# Transform z(x) to Z(x⁻¹) = U(x⁻¹) + iV(x⁻¹)
2016-08-12 09:14:03 +00:00
my $U = $u;
my $V = $v;
fft($U,$V);
2016-08-14 02:45:00 +00:00
2016-08-12 09:14:03 +00:00
# Determine frequency coordinates
my $num_elements = nelem($U);
say "Found $num_elements elements.";
$f = ($num_elements % 2 == 0) ?
$U->xlinvals(
-(${num_elements}/2-1)/${num_elements}/${xres},
1/2/${xres}
)->rotate(-(${num_elements}/2 -1))
:
$U->xlinvals(
-(${num_elements}/2-0.5)/${num_elements}/${xres},
(${num_elements}/2-0.5)/${num_elements}/${xres}
)->rotate(-(${num_elements}-1)/2);
2016-08-14 02:45:00 +00:00
# Output frequency-domain tophat
wcols $f, $U, $V, "fft${tophat_count}.tab";
2016-08-13 21:14:57 +00:00
2016-08-14 02:45:00 +00:00
# Calculate x offset
# This currently multiplies the imaginary component by -1,
# and I really need to figure out why this is necessary for
# proper output.
2016-08-16 12:33:21 +00:00
my $φdiff = atan2(-1*$V,$U);
wcols $f,$φdiff,"analyses/tables/tophat_φdiff${tophat_count}.tab";
2016-08-14 08:15:15 +00:00
2016-08-14 02:45:00 +00:00
my $offset = $φdiff/($_2π*$f);
# Output frequency-domain time delay for given tophat
2016-08-14 02:45:00 +00:00
wcols $f,$offset,"analyses/tables/tophat_fft${tophat_count}.tab";
2016-08-12 09:14:03 +00:00
}
sub tophat {
(my $mean,my $width) = @_;
my $halfwidth = $width/2;
my @vals = ();
2016-08-14 02:45:00 +00:00
for (my $x_coord = $xmin; $x_coord <= $xmax; $x_coord += $xres) {
push @vals, ($x_coord >= ($mean - $halfwidth) &&
$x_coord <= ($mean + $halfwidth)) ? 1/$width : 0;
}
return pdl(@vals);
}