5 # Copyright (c) 1999 Dirk Koopman G1TLH
7 # as fixed by Steve Franke K9AN
12 my ($self, $line) = @_;
13 my @f = split /\s+/, $line;
15 my $prefix = uc shift @f;
16 return (1, $self->msg('e4')) unless $prefix;
23 $hr2 = $f if $f =~ /^\d+$/;
26 $hr2 = 2 if !$hr2 || $hr2 < 2;
27 $hr2 = 24 if $hr2 > 24;
32 my ($pre, $a) = Prefix::extract($prefix);
34 # calc bearings and distance
35 my ($d, $b1, $b2); # distance, bearing from TX and from RX
36 my ($lat2, $lon2); # lats and longs in radians
37 my $lat1 = $self->user->lat;
38 my $lon1 = $self->user->long;
39 my $loc1 = $self->user->qth || "unknown";
41 if (!$lon1 && !$lat1) {
42 push @out, $self->msg('heade1');
43 $lat1 = $main::mylatitude;
44 $lon1 = $main::mylongitude;
49 ($b1, $d) = DXBearing::bdist($lat1, $lon1, $lat2, $lon2);
50 ($b2, undef) = DXBearing::bdist($lat2, $lon2, $lat1, $lon1);
52 # convert stuff into radians
65 $b1 -= $pi2 if ($b1 >= $pi2);
67 $b2 -= $pi2 if ($b2 >= $pi2);
71 my ($hr1, $day, $month) = (gmtime($main::systime))[2,3,4];
73 my $flux = Geomag::sfi;
74 my $ssn = Minimuf::spots($flux);
76 my $theta; # path angle (rad)
78 $theta=$theta+2.*$pi if( $theta <= -$pi);
79 $theta=$theta-2.*$pi if( $theta >= $pi);
81 my ($lats, $lons); # subsolar coordinates (rad)
82 my $dB1 = 26; # transmitter output power (dBW)
84 my $delay; # path delay (ms)
85 my $psi; # sun zenith angle (rad)
86 my ($ftemp, $gtemp); # my $temps
87 my ($i, $j, $h, $n); # int temps
88 my $offset; # offset for local time (hours)
89 my $fcF; # F-layer critical frequency (MHz)
90 my $phiF; # F-layer angle of incidence (rad)
91 my $hop; # number of ray hops
92 my $beta1; # elevation angle (rad)
93 my $dhop; # hop great-circle distance (rad)
94 my $height; # height of F layer (km)
95 my $time; # time of day (hour)
96 my $rsens = -128; # RX sensitivity
99 my @freq = qw(1.8 3.5 7.0 10.1 14.0 18.1 21.0 24.9 28.0 50.0); # working frequencies (MHz)
100 my $nfreq = @freq; # number of frequencies
101 my @mufE; # maximum E-layer MUF (MHz)
102 my @mufF; # minimum F-layer MUF (MHz)
103 my @absorp; # ionospheric absorption coefficient
104 my @dB2; # receive power (dBm)
105 my @path; # path length (km)
106 my @beta; # elevation angle (rad)
107 my @daynight; # path flags
109 # calculate hops, elevation angle, F-layer incidence, delay.
110 $hop = int ($d / (2 * acos($R / ($R + $hF))));
112 while ($beta1 < $MINBETA) {
114 $dhop = $d / ($hop * 2);
115 $beta1 = atan((cos($dhop) - $R / ($R + $hF)) / sin($dhop));
117 $ftemp = $R * cos($beta1) / ($R + $hF);
118 $phiF = atan($ftemp / sqrt(1 - $ftemp * $ftemp));
119 $delay = ((2 * $hop * sin($dhop) * ($R + $hF)) / cos($beta1) / $VOFL) * 1e6;
121 # print summary of data so far
122 push @out, sprintf("RxSens: $rsens dBM SFI:%4.0f R:%4.0f Month: $month Day: $day", $flux, $ssn);
123 push @out, sprintf("Power : %3.0f dBW Distance:%6.0f km Delay:%5.1f ms", $dB1, $d * $R, $delay);
124 push @out, sprintf("Location Lat / Long Azim");
125 push @out, sprintf("%-30.30s %-18s %3.0f", $loc1, DXBearing::lltos($lat1*$r2d, -$lon1*$r2d), $b1 * $r2d);
126 push @out, sprintf("%-30.30s %-18s %3.0f", $a->name, DXBearing::lltos($lat2*$r2d, -$lon2*$r2d), $b2 * $r2d);
127 my $head = "UT LT MUF Zen";
128 for ($i = 0; $i < $nfreq; $i++) {
129 $head .= sprintf "%5.1f", $freq[$i];
135 # Hour loop: This loop determines the min-hop path and next two
136 # higher-hop paths. It selects the most likely path for each
137 # frequency and calculates the receive power. The F-layer
138 # critical frequency is computed directly from MINIMUF 3.5 and
141 $offset = int ($lon2 * 24. / $pi2);
142 for ($hour = $hr1; $hour < $hr2+$hr1; $hour++) {
147 $time = $dh - $offset;
148 $time += 24 if ($time < 0);
149 $time -= 24 if ($time >= 24);
150 my $out = sprintf("%2.0f %2.0f", $dh, $time);
151 $ftemp = Minimuf::minimuf($flux, $month, $day, $dh, $lat1, $lon1, $lat2, $lon2);
152 $fcF = $ftemp * cos($phiF);
154 # Calculate subsolar coordinates.
155 $ftemp = ($month - 1) * 365.25 / 12. + $day - 80.;
156 $lats = 23.5 * $d2r * sin($ftemp / 365.25 * $pi2);
157 $lons = ($dh * 15. - 180.) * $d2r;
159 # Path loop: This loop determines the geometry of the
160 # min-hop path and the next two higher-hop paths. It
161 # calculates the minimum F-layer MUF, maximum E-layer
162 # MUF and ionospheric absorption factor for each
164 for ($h = $hop; $h < $hop + 3; $h++) {
166 # We assume the F layer height increases during
167 # the day and decreases at night, as determined
168 # at the midpoint of the path.
170 $psi = Minimuf::zenith($d / 2, $lat1, $lon1, $b1, $theta, $lats, $lons);
176 $dhop = $d / ($h * 2.);
177 $beta[$h] = atan((cos($dhop) - $R / ($R + $height)) / sin($dhop));
178 $path[$h] = 2 * $h * sin($dhop) * ($R + $height) / cos($beta[$h]);
179 Minimuf::ion($h, $d, $fcF, $ssn, $lat1, $lon1, $b1, $theta, $lats, $lons, \@daynight, \@mufE, \@mufF, \@absorp);
182 # Display one line for this hour.
183 $out .= sprintf("%5.1f%4.0f ", $mufF[$hop], 90 - $psi * $r2d);
185 for ($i = 0; $i < $nfreq; $i++) {
186 $n = Minimuf::pathloss($hop, $freq[$i], 20, $rsens, 0, \@daynight, \@beta, \@path, \@mufF, \@mufE, \@absorp, \@dB2);
187 my $s = Minimuf::ds($n, $rsens, \@dB2, \@daynight);