| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Astro::Misc; | 
| 2 | 1 |  |  | 1 |  | 608 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 52 |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | =head1 NAME | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | Astro::Misc - Miscellaneous astronomical routines | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | use Astro::Misc; | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | $U = calc_U($flux, $dist, $freq); | 
| 13 |  |  |  |  |  |  | ($dist1, $dist2)= kindist($ra, $dec, $vel, $epoch, $model); | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | Astro::Misc contains an assorted set Perl routines for doing various | 
| 18 |  |  |  |  |  |  | astronomical calculations. | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | =head1 AUTHOR | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | Chris Phillips  Chris.Phillips@csiro.au | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | =cut | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | BEGIN { | 
| 30 | 1 |  |  | 1 |  | 5 | use Exporter (); | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 26 |  | 
| 31 | 1 |  |  |  |  | 184 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL | 
| 32 | 1 |  |  | 1 |  | 4 | $Temp $parsecAU $au2km $G $c @ThompsonData); | 
|  | 1 |  |  |  |  | 1 |  | 
| 33 | 1 |  |  | 1 |  | 2 | $VERSION = '1.01'; | 
| 34 | 1 |  |  |  |  | 11 | @ISA = qw(Exporter); | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 1 |  |  |  |  | 2 | @EXPORT      = qw( read_possm calc_U calc_Nl lum2spectral | 
| 37 |  |  |  |  |  |  | Nl2spectral kindist); | 
| 38 | 1 |  |  |  |  | 5 | @EXPORT_OK   = qw ( $Temp read_lovas a model_1 model_2 @ThompsonData $c); | 
| 39 | 1 |  |  |  |  | 49 | @EXPORT_FAIL = qw ( ); | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 1 |  |  | 1 |  | 6 | use Carp; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 69 |  | 
| 42 | 1 |  |  | 1 |  | 6 | use POSIX qw( asin log10); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 9 |  | 
| 43 |  |  |  |  |  |  |  | 
| 44 | 1 |  |  | 1 |  | 119 | use Astro::Time qw( $PI ); | 
|  | 1 |  |  |  |  | 18 |  | 
|  | 1 |  |  |  |  | 115 |  | 
| 45 | 1 |  |  | 1 |  | 7 | use Astro::Coord qw( fk5fk4 fk4gal ); | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 81 |  | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | $parsecAU = 206265;        # The length of one parsec in AU | 
| 50 |  |  |  |  |  |  | $au2km = 149.59787066e6;   # Number of km in one AU | 
| 51 |  |  |  |  |  |  | $G = 6.67e-11;             # Gravitational constant | 
| 52 |  |  |  |  |  |  | $c = 2.99792458e5;         # speed of light in km/s | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | $Temp = 1e4;  # Electron temperature | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | # Load up the data from Thompson 1984 ApJ 283 165 Table 1 | 
| 57 | 1 |  |  | 1 |  | 6 | use constant SPEC => 0; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 61 |  | 
| 58 | 1 |  |  | 1 |  | 5 | use constant LUM => 2; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 35 |  | 
| 59 | 1 |  |  | 1 |  | 4 | use constant NL => 5; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 3325 |  | 
| 60 |  |  |  |  |  |  | @ThompsonData = (); | 
| 61 |  |  |  |  |  |  | while () { | 
| 62 |  |  |  |  |  |  | push @ThompsonData, [split]; | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | =item B | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | Read_possm interprets the output file from the AIPS POSSM task. | 
| 68 |  |  |  |  |  |  | the task may be called repeatably if there is more than one POSSM | 
| 69 |  |  |  |  |  |  | output in the file. The file must be open before calling | 
| 70 |  |  |  |  |  |  | read_possm, using the FileHandle module. The data from the possm | 
| 71 |  |  |  |  |  |  | plot is returned in a hash. Some of the header values are returned | 
| 72 |  |  |  |  |  |  | as scalar values while the actual plot values are returned as | 
| 73 |  |  |  |  |  |  | references to arrays. The scalar values returned are: | 
| 74 |  |  |  |  |  |  | SOURCE, DATE, TIME, BANDWIDTH, TYPE (='A&P'||'R&I') | 
| 75 |  |  |  |  |  |  | The array references are: CHANNEL, | 
| 76 |  |  |  |  |  |  | VELOCITY, FREQUENCY, AMPLITUDE, PHASE, ANTENNA | 
| 77 |  |  |  |  |  |  | The global variable $Astro::Misc:oldpossm (default=0) controls whether | 
| 78 |  |  |  |  |  |  | old or new style possm plots are read.  For oldpossm=1, one of | 
| 79 |  |  |  |  |  |  | VELOCITY or FREQUENCY will be a reference to an empty list (but the | 
| 80 |  |  |  |  |  |  | hash value IS defined). | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | Usage:    use FileHandle | 
| 83 |  |  |  |  |  |  | my $fh = FileHandle->new(); | 
| 84 |  |  |  |  |  |  | my %ahash = (); | 
| 85 |  |  |  |  |  |  | open($fh, 'possmfile'); | 
| 86 |  |  |  |  |  |  | read_possm($fh, %ahash); | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | Returns:  0 on success (but not hit eof) | 
| 89 |  |  |  |  |  |  | 1 on success (and hit eof) | 
| 90 |  |  |  |  |  |  | 2 on premature eof | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | Examples of hash usage: | 
| 93 |  |  |  |  |  |  | $hash{SOURCE}         # Source name | 
| 94 |  |  |  |  |  |  | @{$hash{VELOCITY}}    # Array of velocity values | 
| 95 |  |  |  |  |  |  | ${$hash{PHASE}}[4]    # The fifth phase value | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | =cut | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | sub read_possm ($\%) { | 
| 101 |  |  |  |  |  |  |  | 
| 102 | 0 |  |  | 0 | 1 |  | my($fh, $hashref) = @_; | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | # Initialise the hash ref | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 0 |  |  |  |  |  | $$hashref{CHANNEL} = [()]; | 
| 107 | 0 |  |  |  |  |  | $$hashref{VELOCITY} = [()]; | 
| 108 | 0 |  |  |  |  |  | $$hashref{FREQUENCY} = [()]; | 
| 109 | 0 |  |  |  |  |  | $$hashref{AMPLITUDE} = [()]; | 
| 110 | 0 |  |  |  |  |  | $$hashref{PHASE} = [()]; | 
| 111 | 0 |  |  |  |  |  | $$hashref{ANTENNA} = [()]; | 
| 112 |  |  |  |  |  |  |  | 
| 113 | 0 |  |  |  |  |  | my $eof = 1; | 
| 114 |  |  |  |  |  |  | # Read the header section | 
| 115 | 0 |  |  |  |  |  | while (<$fh>) { | 
| 116 | 0 | 0 |  |  |  |  | if (/^Source:\s*(\S*)/) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 117 | 0 |  |  |  |  |  | $$hashref{SOURCE} = $1; | 
| 118 |  |  |  |  |  |  | } elsif (/^OBS\.\sDATE:\s(\S+)\s+Time\sof\srecord:\s+ | 
| 119 |  |  |  |  |  |  | (\d+\/\s+\d+\s+\d+\s+\d+\.\d+)/x) { | 
| 120 | 0 |  |  |  |  |  | $$hashref{DATE} = $1; | 
| 121 | 0 |  |  |  |  |  | $$hashref{TIME} = $2; | 
| 122 |  |  |  |  |  |  | } elsif (/^Bw \(\S+\):\s+(\S+)/) { | 
| 123 | 0 |  |  |  |  |  | $$hashref{BANDWIDTH} = $1; | 
| 124 |  |  |  |  |  |  | } elsif (/^Antenna\s#\s+\d+\s+name:\s+(\S+)/) { | 
| 125 | 0 |  |  |  |  |  | push @{$$hashref{ANTENNA}}, $1; | 
|  | 0 |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | } elsif (/^DATA/) { | 
| 127 | 0 |  |  |  |  |  | $eof = 0; | 
| 128 | 0 |  |  |  |  |  | last; | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  | } | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 0 | 0 |  |  |  |  | return 2 if $eof; | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | #Skip until find data | 
| 135 | 0 |  |  |  |  |  | $eof = 1; | 
| 136 | 0 |  |  |  |  |  | my $velocity = 0; | 
| 137 | 0 |  |  |  |  |  | while (<$fh>) { | 
| 138 | 0 | 0 |  |  |  |  | if ($astro::oldpossm) { | 
| 139 | 0 | 0 |  |  |  |  | if (/Channel.*IF.*(Velocity|Frequency).*(Ampl|Real).*(Phase|Imag)/) { | 
| 140 | 0 | 0 |  |  |  |  | $velocity = 1 if ($1 eq 'Velocity'); | 
| 141 | 0 | 0 |  |  |  |  | if ($2 eq 'Ampl') { | 
| 142 | 0 |  |  |  |  |  | $$hashref{TYPE} = 'A&P'; | 
| 143 |  |  |  |  |  |  | } else { | 
| 144 | 0 |  |  |  |  |  | $$hashref{TYPE} = 'R&I'; | 
| 145 |  |  |  |  |  |  | } | 
| 146 | 0 |  |  |  |  |  | $eof = 0; | 
| 147 | 0 |  |  |  |  |  | last; | 
| 148 |  |  |  |  |  |  | } | 
| 149 |  |  |  |  |  |  | } else { | 
| 150 |  |  |  |  |  |  | # 5/6/03 Minor change. No time to fix properly bugger | 
| 151 |  |  |  |  |  |  | #      if (/Channel.*IF.*Frequency.*Velocity.*(Ampl|Real).*(Phase|Imag)/) { | 
| 152 | 0 | 0 |  |  |  |  | if (/Channel.*IF.*Polar.*Frequency.*Velocity.*(Ampl|Real).*(Phase|Imag)/) { | 
| 153 | 0 |  |  |  |  |  | $eof = 0; | 
| 154 | 0 | 0 |  |  |  |  | if ($1 eq 'Ampl') { | 
| 155 | 0 |  |  |  |  |  | $$hashref{TYPE} = 'A&P'; | 
| 156 |  |  |  |  |  |  | } else { | 
| 157 | 0 |  |  |  |  |  | $$hashref{TYPE} = 'R&I'; | 
| 158 |  |  |  |  |  |  | } | 
| 159 | 0 |  |  |  |  |  | last; | 
| 160 |  |  |  |  |  |  | } | 
| 161 |  |  |  |  |  |  | } | 
| 162 |  |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  |  | 
| 164 | 0 | 0 |  |  |  |  | croak "$0: premature EOF" if $eof; | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | # Read the data in | 
| 167 | 0 |  |  |  |  |  | $eof = 1; | 
| 168 | 0 |  |  |  |  |  | my $n = 0; | 
| 169 | 0 |  |  |  |  |  | while (<$fh>) { | 
| 170 | 0 | 0 | 0 |  |  |  | if ($astro::oldpossm && /\s*(\d+)\s+           # Channel | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | \d+\s+                                # IF | 
| 172 |  |  |  |  |  |  | ([-+]?\d+\.\d*(?:[Ee][\-+]\d+)?)\s+    # Velocity Frequency | 
| 173 |  |  |  |  |  |  | ([-+]?\d+\.\d*(?:[Ee][\-+]\d+)?)\s+    # Amplitude | 
| 174 |  |  |  |  |  |  | ([-+]?\d+\.\d*)                        # Phase | 
| 175 |  |  |  |  |  |  | /x) { | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 0 |  |  |  |  |  | $n++; | 
| 178 | 0 |  |  |  |  |  | push(@{$$hashref{CHANNEL}},$1); | 
|  | 0 |  |  |  |  |  |  | 
| 179 | 0 | 0 |  |  |  |  | if ($velocity) { | 
| 180 | 0 |  |  |  |  |  | push(@{$$hashref{VELOCITY}},$2); | 
|  | 0 |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | } else { | 
| 182 | 0 |  |  |  |  |  | push(@{$$hashref{FREQUENCY}},$2); | 
|  | 0 |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | } | 
| 184 | 0 |  |  |  |  |  | push(@{$$hashref{AMPLITUDE}},$3); | 
|  | 0 |  |  |  |  |  |  | 
| 185 | 0 |  |  |  |  |  | push(@{$$hashref{PHASE}},$4); | 
|  | 0 |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | } elsif (/\s*(\d+)\s+                          # Channel | 
| 187 |  |  |  |  |  |  | \d+\s+                                # IF | 
| 188 |  |  |  |  |  |  | \S+\s+                                # Polar | 
| 189 |  |  |  |  |  |  | (\d+\.\d*(?:[Ee][\-+]\d+)?)\s+        # Frequency | 
| 190 |  |  |  |  |  |  | ([-+]?\d+\.\d*(?:[Ee][\-+]\d+)?)\s+   # Velocity | 
| 191 |  |  |  |  |  |  | ([-+]?\d+\.\d*(?:[Ee][\-+]\d+)?)\s+   # Amplitude - Real | 
| 192 |  |  |  |  |  |  | ([-+]?\d+\.\d*)                       # Phase - Imag | 
| 193 |  |  |  |  |  |  | /x) { | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 0 |  |  |  |  |  | $n++; | 
| 196 | 0 |  |  |  |  |  | push(@{$$hashref{CHANNEL}},$1); | 
|  | 0 |  |  |  |  |  |  | 
| 197 | 0 |  |  |  |  |  | push(@{$$hashref{FREQUENCY}},$2); | 
|  | 0 |  |  |  |  |  |  | 
| 198 | 0 |  |  |  |  |  | push(@{$$hashref{VELOCITY}},$3); | 
|  | 0 |  |  |  |  |  |  | 
| 199 | 0 |  |  |  |  |  | push(@{$$hashref{AMPLITUDE}},$4); | 
|  | 0 |  |  |  |  |  |  | 
| 200 | 0 |  |  |  |  |  | push(@{$$hashref{PHASE}},$5); | 
|  | 0 |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | } elsif (/\s*\d+.*FLAGGED/) { | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | } elsif (/Header/) {  #Next plot | 
| 204 | 0 |  |  |  |  |  | $eof = 0; | 
| 205 | 0 |  |  |  |  |  | last; | 
| 206 |  |  |  |  |  |  | } else { | 
| 207 | 0 |  |  |  |  |  | print STDERR '** '; | 
| 208 | 0 |  |  |  |  |  | print STDERR; | 
| 209 |  |  |  |  |  |  | } | 
| 210 |  |  |  |  |  |  | } | 
| 211 |  |  |  |  |  |  |  | 
| 212 | 0 | 0 |  |  |  |  | croak "$0: No Data read\n" if ($n == 0); | 
| 213 |  |  |  |  |  |  |  | 
| 214 | 0 |  |  |  |  |  | return $eof; | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | =item B | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | Read_lovas read the Lovas "Recommended Rest Frequencies for Observed | 
| 221 |  |  |  |  |  |  | Interstellar Molecular Microwave Transitions - 1991 Revision" | 
| 222 |  |  |  |  |  |  | (J. Phys. Chem. Ref. Data, 21, 181-272, 1992). Alpha quality!! | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | my @lovas = read_lovas($fname); | 
| 225 |  |  |  |  |  |  | my @lovas = read_lovas($fname, $minfreq, $maxfreq); | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =cut | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | # Probably does not work !!! | 
| 230 |  |  |  |  |  |  | sub read_lovas ($;$$) { | 
| 231 | 0 |  |  | 0 | 1 |  | warn 'Using Beta routine'; | 
| 232 | 0 |  |  |  |  |  | my($fname, $min, $max) = @_; | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 0 | 0 |  |  |  |  | if (!open(LOVAS, $fname)) { | 
| 235 | 0 |  |  |  |  |  | carp "Could not open $fname: $!\n"; | 
| 236 | 0 |  |  |  |  |  | return undef; | 
| 237 |  |  |  |  |  |  | } | 
| 238 |  |  |  |  |  |  |  | 
| 239 | 0 |  |  |  |  |  | my ($freq, $calc, $uncert, $molecule, $form, $tsys, $source, $telescope, $ref); | 
| 240 | 0 |  |  |  |  |  | my @lovas = (); | 
| 241 |  |  |  |  |  |  |  | 
| 242 | 0 |  |  |  |  |  | while () { | 
| 243 | 0 |  |  |  |  |  | chomp; | 
| 244 |  |  |  |  |  |  |  | 
| 245 | 0 |  |  |  |  |  | $freq = substr $_, 1, 16; | 
| 246 | 0 |  |  |  |  |  | $molecule = substr $_, 18, 11; | 
| 247 | 0 |  |  |  |  |  | $form = substr $_, 29, 28; | 
| 248 | 0 |  |  |  |  |  | $c = substr $_, 57, 1;  # Could be either formulae or Tsys | 
| 249 | 0 |  |  |  |  |  | $tsys = substr $_, 58, 7; | 
| 250 | 0 |  |  |  |  |  | $source = substr $_, 65, 15; | 
| 251 | 0 |  |  |  |  |  | $telescope = substr $_, 81, 12; | 
| 252 | 0 |  |  |  |  |  | $ref = substr $_, 94; | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | # Clean up the strings | 
| 255 |  |  |  |  |  |  |  | 
| 256 | 0 |  |  |  |  |  | $freq =~ s/^\s+//; | 
| 257 | 0 |  |  |  |  |  | $freq =~ s/\s+$//; | 
| 258 | 0 |  |  |  |  |  | $molecule =~ s/^\s+//; | 
| 259 | 0 |  |  |  |  |  | $molecule =~ s/\s+$//; | 
| 260 | 0 |  |  |  |  |  | $source =~ s/^\s+//; | 
| 261 | 0 |  |  |  |  |  | $source =~ s/\s+$//; | 
| 262 | 0 |  |  |  |  |  | $telescope =~ s/^\s+//; | 
| 263 | 0 |  |  |  |  |  | $telescope =~ s/\s+$//; | 
| 264 | 0 |  |  |  |  |  | $ref =~ s/^\s+//; | 
| 265 | 0 |  |  |  |  |  | $ref =~ s/\s+$//; | 
| 266 |  |  |  |  |  |  |  | 
| 267 |  |  |  |  |  |  | # Work out the contended column 57; | 
| 268 | 0 | 0 |  |  |  |  | if ($c ne ' ') { | 
| 269 |  |  |  |  |  |  |  | 
| 270 | 0 |  |  |  |  |  | my ($s1) = $tsys =~ /^(\s+)/; | 
| 271 | 0 |  |  |  |  |  | my ($s2) = $form =~ /(\s+)$/; | 
| 272 |  |  |  |  |  |  | # Assign column 57 to the field with the "nearest"  non-blank (preference | 
| 273 |  |  |  |  |  |  | # to Tsys). | 
| 274 | 0 | 0 |  |  |  |  | if (!defined $s1) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 275 | 0 |  |  |  |  |  | $tsys = "$c$tsys"; | 
| 276 |  |  |  |  |  |  | } elsif (!defined $s2) { | 
| 277 | 0 |  |  |  |  |  | $form .= $c; | 
| 278 |  |  |  |  |  |  | }	elsif (length($s2) > length($s1)) { | 
| 279 | 0 |  |  |  |  |  | $tsys = "$c$tsys"; | 
| 280 |  |  |  |  |  |  | } else { | 
| 281 | 0 |  |  |  |  |  | $form .= $c; | 
| 282 |  |  |  |  |  |  | } | 
| 283 |  |  |  |  |  |  | } | 
| 284 |  |  |  |  |  |  |  | 
| 285 | 0 |  |  |  |  |  | $form =~ s/^\s+//; | 
| 286 | 0 |  |  |  |  |  | $form =~ s/\s+$//; | 
| 287 | 0 |  |  |  |  |  | $tsys =~ s/^\s+//; | 
| 288 | 0 |  |  |  |  |  | $tsys =~ s/\s+$//; | 
| 289 |  |  |  |  |  |  |  | 
| 290 |  |  |  |  |  |  | # Clean up unidentified molecules | 
| 291 | 0 | 0 |  |  |  |  | if ($molecule eq 'unidentifie') { | 
| 292 | 0 |  |  |  |  |  | $molecule .= $form; | 
| 293 | 0 |  |  |  |  |  | $form = ''; | 
| 294 |  |  |  |  |  |  | } | 
| 295 |  |  |  |  |  |  |  | 
| 296 | 0 | 0 |  |  |  |  | if ($freq =~ /(.*)\*$/) { | 
| 297 | 0 |  |  |  |  |  | my $oldfreq = $freq; | 
| 298 | 0 |  |  |  |  |  | $freq = $1; | 
| 299 | 0 |  |  |  |  |  | $calc = 1; | 
| 300 | 0 |  |  |  |  |  | $freq =~ s/\s+$//; | 
| 301 | 0 |  |  |  |  |  | print "Using $oldfreq -> \"$freq\"\n"; | 
| 302 |  |  |  |  |  |  | } else { | 
| 303 | 0 |  |  |  |  |  | $calc = 0; | 
| 304 |  |  |  |  |  |  | } | 
| 305 |  |  |  |  |  |  |  | 
| 306 | 0 | 0 |  |  |  |  | if ($freq =~ /([^\s\*\(]*[\d\.])\s*(\*)?\s*(\(\s*\d+\))?/) { | 
| 307 | 0 |  |  |  |  |  | my $oldfreq = $freq; | 
| 308 | 0 |  |  |  |  |  | $freq = $1; | 
| 309 | 0 | 0 |  |  |  |  | if (defined $2) { | 
| 310 | 0 |  |  |  |  |  | $calc = $2; | 
| 311 |  |  |  |  |  |  | } else { | 
| 312 | 0 |  |  |  |  |  | $calc = ' '; | 
| 313 |  |  |  |  |  |  | } | 
| 314 | 0 | 0 |  |  |  |  | if (defined $3) { | 
| 315 | 0 |  |  |  |  |  | $uncert = $3; | 
| 316 |  |  |  |  |  |  | } else { | 
| 317 | 0 |  |  |  |  |  | $uncert = ''; | 
| 318 |  |  |  |  |  |  | } | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | #warn "Used $oldfreq-> $freq:$calc:$uncert\n"; | 
| 321 |  |  |  |  |  |  | } else { | 
| 322 | 0 |  |  |  |  |  | warn "***Failed to parse $freq\n"; | 
| 323 |  |  |  |  |  |  | } | 
| 324 |  |  |  |  |  |  |  | 
| 325 | 0 | 0 | 0 |  |  |  | next if (defined $min && $freq<$min); | 
| 326 | 0 | 0 | 0 |  |  |  | next if (defined $max && $freq>$max); | 
| 327 |  |  |  |  |  |  |  | 
| 328 | 0 |  |  |  |  |  | push @lovas, [$freq, $calc, $uncert, $molecule, $form, $tsys, $source, | 
| 329 |  |  |  |  |  |  | $telescope, $ref]; | 
| 330 |  |  |  |  |  |  |  | 
| 331 |  |  |  |  |  |  | } | 
| 332 | 0 |  |  |  |  |  | close(LOVAS); | 
| 333 |  |  |  |  |  |  |  | 
| 334 | 0 |  |  |  |  |  | return @lovas; | 
| 335 |  |  |  |  |  |  | } | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | # Used internally for calc_U | 
| 338 |  |  |  |  |  |  | # Ref: Mezger & Henderson 1967, ApJ 147 p 471 Eq A.2 | 
| 339 |  |  |  |  |  |  | sub a ($) { | 
| 340 | 0 |  |  | 0 | 0 |  | my $freq = shift; | 
| 341 |  |  |  |  |  |  |  | 
| 342 | 0 |  |  |  |  |  | my $a = 0.336 * $freq**0.1 * $Temp**-0.15 | 
| 343 |  |  |  |  |  |  | * (log(4.995e-2/$freq) + 1.5*log($Temp)); | 
| 344 |  |  |  |  |  |  |  | 
| 345 | 0 |  |  |  |  |  | return($a); | 
| 346 |  |  |  |  |  |  | } | 
| 347 |  |  |  |  |  |  |  | 
| 348 |  |  |  |  |  |  | =item B | 
| 349 |  |  |  |  |  |  |  | 
| 350 |  |  |  |  |  |  | $U = calc_U($flux, $dist, $freq); | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | Calculate U (Excitation Parameter) for an UCHII region | 
| 353 |  |  |  |  |  |  | Based on Eqn 8 in Schraml and Mezger, 1969 | 
| 354 |  |  |  |  |  |  | $flux        Integrated Source Flux Density (Jy) | 
| 355 |  |  |  |  |  |  | $dist        Distance to source (kpc) | 
| 356 |  |  |  |  |  |  | $freq        Frequency of observation (GHz) | 
| 357 |  |  |  |  |  |  | Note: | 
| 358 |  |  |  |  |  |  | Uses the global variable $Astro::Misc::Temp for electron temperature | 
| 359 |  |  |  |  |  |  | Default is 10000K | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | =cut | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | sub calc_U ($$$) { | 
| 364 |  |  |  |  |  |  |  | 
| 365 | 0 |  |  | 0 | 1 |  | my ($flux, $dist, $freq) = @_; | 
| 366 |  |  |  |  |  |  |  | 
| 367 | 0 |  |  |  |  |  | my $U = 4.5526 * ($freq**0.1 / a($freq) * $Temp**0.35 | 
| 368 |  |  |  |  |  |  | * $flux * $dist**2)**(1/3); | 
| 369 | 0 |  |  |  |  |  | return ($U); | 
| 370 |  |  |  |  |  |  | } | 
| 371 |  |  |  |  |  |  |  | 
| 372 |  |  |  |  |  |  | =item B | 
| 373 |  |  |  |  |  |  |  | 
| 374 |  |  |  |  |  |  | $Nl = calc_Nl($U); | 
| 375 |  |  |  |  |  |  |  | 
| 376 |  |  |  |  |  |  | Calculate the Lyman continuum photon flux given U, the Excitation | 
| 377 |  |  |  |  |  |  | Parameter for an UCHII region | 
| 378 |  |  |  |  |  |  | $U is the Excitation Parameter (from calc_U) | 
| 379 |  |  |  |  |  |  | Ref: Kurtz 1994 ApJS 91 p659 Eq (1) (Original Origin unknown) | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  | =cut | 
| 382 |  |  |  |  |  |  |  | 
| 383 |  |  |  |  |  |  | sub calc_Nl ($) { | 
| 384 |  |  |  |  |  |  |  | 
| 385 | 0 |  |  | 0 | 1 |  | my ($U) = @_; | 
| 386 |  |  |  |  |  |  |  | 
| 387 |  |  |  |  |  |  | # This came from Panagia 1973 AJ 78 p929 Eq 5. | 
| 388 |  |  |  |  |  |  | #my $Nl = ($U / 1.0976 / 2.01e-19)**3 * (3.43e-13); | 
| 389 |  |  |  |  |  |  |  | 
| 390 |  |  |  |  |  |  | # This is the same from Kurtz but includes the Electron Temperature | 
| 391 | 0 |  |  |  |  |  | my $Nl = 8.04e46 * $Temp**-0.85 * $U**3; | 
| 392 |  |  |  |  |  |  |  | 
| 393 | 0 |  |  |  |  |  | return $Nl; | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | } | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | ## Replaced by values from Thompson 1984 | 
| 398 |  |  |  |  |  |  | #  my @speclist = ('O4', 'O5', 'O5.5', 'O6', 'O6.5', 'O7', 'O7.5', 'O8', | 
| 399 |  |  |  |  |  |  | #  		'O8.5', 'O9', 'O9.5', 'B0', 'B0.5', 'B1', 'B2', 'B3'); | 
| 400 |  |  |  |  |  |  | #  my @lumlist = (6.11, 5.83, 5.60, 5.40, 5.17, 5.00, 4.92, 4.81, | 
| 401 |  |  |  |  |  |  | #  	       4.73, 4.66, 4.58, 4.40, 4.04, 3.72, 3.46, 3.02); | 
| 402 |  |  |  |  |  |  | #  my @Nllist = (49.93, 49.62, 49.36, 49.08, 49.82, 48.62, 48.51, 48.35, 48.21, | 
| 403 |  |  |  |  |  |  | #  	      48.08, 47.84, 47.36, 46.23, 45.29, 44.65, 43.69); | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | #  die '@lumlist, @speclist and @Nlist must be the same size' | 
| 406 |  |  |  |  |  |  | #      if (scalar(@lumlist) != scalar(@speclist) | 
| 407 |  |  |  |  |  |  | #  	|| scalar(@lumlist) != scalar(@Nllist)); | 
| 408 |  |  |  |  |  |  |  | 
| 409 |  |  |  |  |  |  | #  =item B | 
| 410 |  |  |  |  |  |  |  | 
| 411 |  |  |  |  |  |  | #    $spectral_type = lum2spectral($luminosity); | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | #   Calculate the spectral type of a ZAMS star from its luminosity | 
| 414 |  |  |  |  |  |  | #   Based on Panagia, 1973, ApJ, 78, 929. | 
| 415 |  |  |  |  |  |  | #     $luminosity   Star luminosity (normalised to Lsun) | 
| 416 |  |  |  |  |  |  | #   Returns undef if luminosity is out of range (O4 - B3) | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | #  =cut | 
| 419 |  |  |  |  |  |  |  | 
| 420 |  |  |  |  |  |  | #  sub lum2spectral ($) { | 
| 421 |  |  |  |  |  |  |  | 
| 422 |  |  |  |  |  |  | #    my ($lum) = @_; | 
| 423 |  |  |  |  |  |  | #    $lum = log10($lum); | 
| 424 |  |  |  |  |  |  |  | 
| 425 |  |  |  |  |  |  | #    my $n = scalar (@speclist); | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | #    if ($lum > $lumlist[0]) { | 
| 428 |  |  |  |  |  |  | #      return ">$speclist[0]"; | 
| 429 |  |  |  |  |  |  | #    } elsif ($lum < $lumlist[$n-1]) { | 
| 430 |  |  |  |  |  |  | #      return "<$speclist[$n-1]"; | 
| 431 |  |  |  |  |  |  | #    }; | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | #    my $i = 1; | 
| 434 |  |  |  |  |  |  |  | 
| 435 |  |  |  |  |  |  | #    # Find the closest pair | 
| 436 |  |  |  |  |  |  | #    while ($lum < $lumlist[$i]) { | 
| 437 |  |  |  |  |  |  | #      $i++; | 
| 438 |  |  |  |  |  |  | #    } | 
| 439 |  |  |  |  |  |  | #    # Return the closest one | 
| 440 |  |  |  |  |  |  | #    if ($lumlist[$i-1]-$lum > $lum - $lumlist[$i]) { | 
| 441 |  |  |  |  |  |  | #      return $speclist[$i]; | 
| 442 |  |  |  |  |  |  | #    } else { | 
| 443 |  |  |  |  |  |  | #      return $speclist[$i-1]; | 
| 444 |  |  |  |  |  |  | #    } | 
| 445 |  |  |  |  |  |  | #  } | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | #  =item B | 
| 448 |  |  |  |  |  |  |  | 
| 449 |  |  |  |  |  |  | #    $spectral = Nl2spectral($Nl); | 
| 450 |  |  |  |  |  |  |  | 
| 451 |  |  |  |  |  |  | #   Calculate the spectral type of a ZAMS star from its flux of | 
| 452 |  |  |  |  |  |  | #   Lyman Continuum Photons (Nl) | 
| 453 |  |  |  |  |  |  | #   Based on Panagia, 1973, ApJ, 78, 929 | 
| 454 |  |  |  |  |  |  | #     $Nl     Flux of Lyman Continuum Photons | 
| 455 |  |  |  |  |  |  | #   Returns undef if luminosity is out of range (O4 - B3) | 
| 456 |  |  |  |  |  |  |  | 
| 457 |  |  |  |  |  |  | #  =cut | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | #  sub Nl2spectral ($) { | 
| 460 |  |  |  |  |  |  |  | 
| 461 |  |  |  |  |  |  | #    my ($Nl) = @_; | 
| 462 |  |  |  |  |  |  | #    $Nl = log10($Nl); | 
| 463 |  |  |  |  |  |  |  | 
| 464 |  |  |  |  |  |  | #    my $n = scalar (@speclist); | 
| 465 |  |  |  |  |  |  |  | 
| 466 |  |  |  |  |  |  | #    if ($Nl > $Nllist[0]) { | 
| 467 |  |  |  |  |  |  | #      return ">$speclist[0]"; | 
| 468 |  |  |  |  |  |  | #    } elsif ($Nl < $Nllist[$n-1]) { | 
| 469 |  |  |  |  |  |  | #      return "<$speclist[$n-1]"; | 
| 470 |  |  |  |  |  |  | #    }; | 
| 471 |  |  |  |  |  |  |  | 
| 472 |  |  |  |  |  |  | #    my $i = 1; | 
| 473 |  |  |  |  |  |  |  | 
| 474 |  |  |  |  |  |  | #    # Find the closest pair | 
| 475 |  |  |  |  |  |  | #    while ($Nl < $Nllist[$i]) { | 
| 476 |  |  |  |  |  |  | #      $i++; | 
| 477 |  |  |  |  |  |  | #    } | 
| 478 |  |  |  |  |  |  | #    # Return the closest one | 
| 479 |  |  |  |  |  |  | #    if ($Nllist[$i-1]-$Nl > $Nl - $Nllist[$i]) { | 
| 480 |  |  |  |  |  |  | #      return $speclist[$i]; | 
| 481 |  |  |  |  |  |  | #    } else { | 
| 482 |  |  |  |  |  |  | #      return $speclist[$i-1]; | 
| 483 |  |  |  |  |  |  | #    } | 
| 484 |  |  |  |  |  |  | #  } | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | =item B | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | $spectral_type = lum2spectral($luminosity); | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | Calculate the spectral type of a ZAMS star from its luminosity | 
| 491 |  |  |  |  |  |  | Based on Thompson 1984 ApJ 283 165 Table 1 | 
| 492 |  |  |  |  |  |  | $luminosity   Star luminosity (normalised to Lsun) | 
| 493 |  |  |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | =cut | 
| 495 |  |  |  |  |  |  |  | 
| 496 |  |  |  |  |  |  | sub lum2spectral($) { | 
| 497 | 0 |  |  | 0 | 1 |  | my $lum = log10(shift); | 
| 498 |  |  |  |  |  |  |  | 
| 499 | 0 |  |  |  |  |  | my $n = scalar (@ThompsonData); | 
| 500 | 0 | 0 |  |  |  |  | if ($lum < $ThompsonData[0][LUM]) { | 
|  |  | 0 |  |  |  |  |  | 
| 501 | 0 |  |  |  |  |  | return "<$ThompsonData[0][SPEC]"; | 
| 502 |  |  |  |  |  |  | } elsif ($lum > $ThompsonData[$n-1][LUM]) { | 
| 503 | 0 |  |  |  |  |  | return ">$ThompsonData[$n-1][SPEC]"; | 
| 504 |  |  |  |  |  |  | }; | 
| 505 |  |  |  |  |  |  |  | 
| 506 | 0 |  |  |  |  |  | $n = 1; | 
| 507 |  |  |  |  |  |  | # Find the closest pair | 
| 508 | 0 |  |  |  |  |  | while ($lum > $ThompsonData[$n][LUM]) { | 
| 509 | 0 |  |  |  |  |  | $n++; | 
| 510 |  |  |  |  |  |  | } | 
| 511 |  |  |  |  |  |  | # Return the closest one | 
| 512 | 0 | 0 |  |  |  |  | if ($ThompsonData[$n][LUM]-$lum < $lum - $ThompsonData[$n-1][LUM]) { | 
| 513 | 0 |  |  |  |  |  | return $ThompsonData[$n][SPEC]; | 
| 514 |  |  |  |  |  |  | } else { | 
| 515 | 0 |  |  |  |  |  | return $ThompsonData[$n-1][SPEC]; | 
| 516 |  |  |  |  |  |  | } | 
| 517 |  |  |  |  |  |  | } | 
| 518 |  |  |  |  |  |  |  | 
| 519 |  |  |  |  |  |  | =item B | 
| 520 |  |  |  |  |  |  |  | 
| 521 |  |  |  |  |  |  | $spectral = Nl2spectral($Nl); | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  | Calculate the spectral type of a ZAMS star from its flux of | 
| 524 |  |  |  |  |  |  | Lyman Continuum Photons (Nl) | 
| 525 |  |  |  |  |  |  | Based on Panagia, 1973, ApJ, 78, 929 | 
| 526 |  |  |  |  |  |  | $Nl     Flux of Lyman Continuum Photons | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | =cut | 
| 529 |  |  |  |  |  |  |  | 
| 530 |  |  |  |  |  |  | sub Nl2spectral ($) { | 
| 531 | 0 |  |  | 0 | 1 |  | my $Nl = log10(shift); | 
| 532 |  |  |  |  |  |  |  | 
| 533 | 0 |  |  |  |  |  | my $n = scalar (@ThompsonData); | 
| 534 |  |  |  |  |  |  |  | 
| 535 | 0 | 0 |  |  |  |  | if ($Nl < $ThompsonData[0][NL]) { | 
|  |  | 0 |  |  |  |  |  | 
| 536 | 0 |  |  |  |  |  | return "<$ThompsonData[0][SPEC]"; | 
| 537 |  |  |  |  |  |  | } elsif ($Nl > $ThompsonData[$n-1][NL]) { | 
| 538 | 0 |  |  |  |  |  | return ">$ThompsonData[$n-1][SPEC]"; | 
| 539 |  |  |  |  |  |  | }; | 
| 540 |  |  |  |  |  |  |  | 
| 541 | 0 |  |  |  |  |  | $n = 1; | 
| 542 |  |  |  |  |  |  | # Find the closest pair | 
| 543 | 0 |  |  |  |  |  | while ($Nl > $ThompsonData[$n][NL]) { | 
| 544 | 0 |  |  |  |  |  | $n++; | 
| 545 |  |  |  |  |  |  | } | 
| 546 |  |  |  |  |  |  | # Return the closest one | 
| 547 | 0 | 0 |  |  |  |  | if ($ThompsonData[$n][NL]-$Nl < $Nl - $ThompsonData[$n-1][NL]) { | 
| 548 | 0 |  |  |  |  |  | return $ThompsonData[$n][SPEC]; | 
| 549 |  |  |  |  |  |  | } else { | 
| 550 | 0 |  |  |  |  |  | return $ThompsonData[$n-1][SPEC]; | 
| 551 |  |  |  |  |  |  | } | 
| 552 |  |  |  |  |  |  | } | 
| 553 |  |  |  |  |  |  |  | 
| 554 |  |  |  |  |  |  | =item B | 
| 555 |  |  |  |  |  |  |  | 
| 556 |  |  |  |  |  |  | ($dist1, $dist2)= kindist($ra, $dec, $vel, $epoch, $model); | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  | Calculate the kinematic distance to an object | 
| 559 |  |  |  |  |  |  | $dist1, $dist2  Near/Far distance (kpc) | 
| 560 |  |  |  |  |  |  | $ra             RA of object (turns) | 
| 561 |  |  |  |  |  |  | $dec            Dec of object (turns) | 
| 562 |  |  |  |  |  |  | $vel            LSR Velocity (km/s) | 
| 563 |  |  |  |  |  |  | $epoch          Epoch of coords (J2000/J/B1950/B) | 
| 564 |  |  |  |  |  |  | $model          Model to use (1 or 2) | 
| 565 |  |  |  |  |  |  |  | 
| 566 |  |  |  |  |  |  | Note: | 
| 567 |  |  |  |  |  |  | Model 1 is based on Brand and Blitz, 1993, A&A, 275, 67-90. | 
| 568 |  |  |  |  |  |  | Model 2 has unknown origin. | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | =cut | 
| 571 |  |  |  |  |  |  |  | 
| 572 |  |  |  |  |  |  | sub kindist ($$$$$) { | 
| 573 |  |  |  |  |  |  |  | 
| 574 | 0 |  |  | 0 | 1 |  | my ($ra, $dec, $vel, $epoch, $model) = @_; | 
| 575 | 0 |  |  |  |  |  | my ($l, $b, $dist1, $dist2, $psi, $phi, $phid, $psid); | 
| 576 | 0 |  |  |  |  |  | $l = 0.0; | 
| 577 | 0 |  |  |  |  |  | $b = 0.0; | 
| 578 |  |  |  |  |  |  |  | 
| 579 | 0 | 0 | 0 |  |  |  | if (($epoch eq 'J2000') || ($epoch eq 'J')) { | 
| 580 | 0 |  |  |  |  |  | ($ra, $dec) = fk5fk4($ra, $dec); | 
| 581 |  |  |  |  |  |  | } | 
| 582 | 0 |  |  |  |  |  | ($l, $b) = fk4gal($ra, $dec); | 
| 583 | 0 |  |  |  |  |  | $l *= 2.0*$PI; | 
| 584 | 0 |  |  |  |  |  | $b *= 2.0*$PI; | 
| 585 |  |  |  |  |  |  |  | 
| 586 | 0 | 0 | 0 |  |  |  | croak "\$model must equal 1 or 2\n" | 
| 587 |  |  |  |  |  |  | if ($model != 1 && $model != 2) ; | 
| 588 |  |  |  |  |  |  |  | 
| 589 | 0 |  |  |  |  |  | my $Ro = 8.5; | 
| 590 | 0 |  |  |  |  |  | my $THETAo = 220; | 
| 591 | 0 |  |  |  |  |  | my $R = 0.0004; | 
| 592 | 0 |  |  |  |  |  | my $Wo = $THETAo/$Ro; | 
| 593 | 0 |  |  |  |  |  | my $W = $vel/($Ro * sin($l)) + $Wo; | 
| 594 |  |  |  |  |  |  |  | 
| 595 | 0 |  |  |  |  |  | my ($sampW); | 
| 596 | 0 |  |  |  |  |  | my $eps = 9999999.0; | 
| 597 | 0 |  |  |  |  |  | while ($eps > 0.1) { | 
| 598 | 0 |  |  |  |  |  | $R += 0.1; | 
| 599 | 0 | 0 |  |  |  |  | if ($model == 1) { | 
| 600 | 0 |  |  |  |  |  | $sampW = model_1($R); | 
| 601 |  |  |  |  |  |  | } else { | 
| 602 | 0 |  |  |  |  |  | $sampW = model_2($R); | 
| 603 |  |  |  |  |  |  | } | 
| 604 | 0 |  |  |  |  |  | $eps = abs($W - $sampW)/$W; | 
| 605 | 0 | 0 |  |  |  |  | if ($R > 5.0*$Ro) { | 
| 606 | 0 |  |  |  |  |  | warn "Could not find within limits.\n"; | 
| 607 | 0 |  |  |  |  |  | $eps = 0.0; | 
| 608 |  |  |  |  |  |  | } | 
| 609 |  |  |  |  |  |  | } | 
| 610 | 0 |  |  |  |  |  | $R = $R - 0.5; | 
| 611 | 0 | 0 |  |  |  |  | $R = 0.0 if ($R < 0.0); | 
| 612 | 0 |  |  |  |  |  | $eps = 9999999.0; | 
| 613 | 0 |  |  |  |  |  | while ($eps > 0.0001) { | 
| 614 | 0 |  |  |  |  |  | $R +=  0.0001; | 
| 615 | 0 | 0 |  |  |  |  | if ($model == 1) { | 
| 616 | 0 |  |  |  |  |  | $sampW = model_1($R); | 
| 617 |  |  |  |  |  |  | } else { | 
| 618 | 0 |  |  |  |  |  | $sampW =  model_2($R); | 
| 619 |  |  |  |  |  |  | } | 
| 620 | 0 |  |  |  |  |  | $eps = abs($W - $sampW)/$W; | 
| 621 | 0 | 0 |  |  |  |  | if ($R > 5.0*$Ro) { | 
| 622 | 0 |  |  |  |  |  | warn "Could not find within limits.\n"; | 
| 623 | 0 |  |  |  |  |  | $eps = 0.0; | 
| 624 |  |  |  |  |  |  | } | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  |  | 
| 627 | 0 | 0 |  |  |  |  | if ( sin($l) * $Ro/$R  > 1.0) { | 
|  |  | 0 |  |  |  |  |  | 
| 628 | 0 |  |  |  |  |  | $psi = $PI/2; | 
| 629 |  |  |  |  |  |  | } elsif ( sin($l)*$Ro/$R  < -1.0) { | 
| 630 | 0 |  |  |  |  |  | $psi = -$PI/2; | 
| 631 |  |  |  |  |  |  | } else { | 
| 632 | 0 |  |  |  |  |  | $psi = asin(sin($l)*$Ro/$R); | 
| 633 |  |  |  |  |  |  | } | 
| 634 | 0 |  |  |  |  |  | $phi = $PI - $psi - $l; | 
| 635 |  |  |  |  |  |  |  | 
| 636 | 0 | 0 |  |  |  |  | if (sin($l) == 0.0) { | 
| 637 | 0 |  |  |  |  |  | $dist1 = 0.0; | 
| 638 | 0 |  |  |  |  |  | $dist2 = 0.0; | 
| 639 |  |  |  |  |  |  | } else { | 
| 640 | 0 |  |  |  |  |  | $dist1 = abs($R*sin($phi)/sin($l)); | 
| 641 | 0 |  |  |  |  |  | $psid = $PI - $psi; | 
| 642 | 0 |  |  |  |  |  | $phid = $PI - $psid - $l; | 
| 643 | 0 |  |  |  |  |  | $dist2 = abs($R*sin($phid)/sin($l)); | 
| 644 |  |  |  |  |  |  | } | 
| 645 |  |  |  |  |  |  |  | 
| 646 | 0 | 0 |  |  |  |  | if ($dist1 <= $dist2) { | 
| 647 | 0 |  |  |  |  |  | return($dist1, $dist2); | 
| 648 |  |  |  |  |  |  | } else { | 
| 649 | 0 |  |  |  |  |  | return($dist2, $dist1); | 
| 650 |  |  |  |  |  |  | } | 
| 651 |  |  |  |  |  |  | } | 
| 652 |  |  |  |  |  |  |  | 
| 653 |  |  |  |  |  |  | sub  model_1 ($) { | 
| 654 |  |  |  |  |  |  | # Model from Brand and Blitz, 1993, A&A, 275, 67-90 | 
| 655 | 0 |  |  | 0 | 0 |  | my ($R) = @_; | 
| 656 |  |  |  |  |  |  |  | 
| 657 | 0 |  |  |  |  |  | my $Ro = 8.5; | 
| 658 | 0 |  |  |  |  |  | my $THETAo = 220; | 
| 659 | 0 |  |  |  |  |  | my $q = 1.00767; | 
| 660 | 0 |  |  |  |  |  | my $rr = 0.0394; | 
| 661 | 0 |  |  |  |  |  | my $s = 0.00712; | 
| 662 |  |  |  |  |  |  | # my $s = 0.00698; | 
| 663 |  |  |  |  |  |  | # my $q = 1.0074; | 
| 664 |  |  |  |  |  |  | # my $rr = 0.0382; | 
| 665 |  |  |  |  |  |  |  | 
| 666 | 0 |  |  |  |  |  | return  (($q*($R/$Ro)**$rr + $s)*$THETAo/$R); | 
| 667 |  |  |  |  |  |  | } | 
| 668 |  |  |  |  |  |  |  | 
| 669 |  |  |  |  |  |  | sub model_2 ($) { | 
| 670 | 0 |  |  | 0 | 0 |  | my ($R) = @_; | 
| 671 |  |  |  |  |  |  |  | 
| 672 | 0 |  |  |  |  |  | my $Ro = 8.5; | 
| 673 | 0 |  |  |  |  |  | my $THETAo = 220; | 
| 674 | 0 |  |  |  |  |  | my @A = (0.0, +3069.81, -15809.8, +43980.1, -68287.3, | 
| 675 |  |  |  |  |  |  | +54904.0, -17731.0); | 
| 676 | 0 |  |  |  |  |  | my @B = (+325.0912, -248.1467, +231.87099, -110.73531, | 
| 677 |  |  |  |  |  |  | +25.073006, -2.110625); | 
| 678 | 0 |  |  |  |  |  | my @C = (-2342.6564, +2507.60391, -1024.068760, +224.562732, | 
| 679 |  |  |  |  |  |  | -28.4080026, +2.0697271, -0.08050808, +0.00129348); | 
| 680 | 0 |  |  |  |  |  | my $D0 = 234.88; | 
| 681 |  |  |  |  |  |  |  | 
| 682 | 0 |  |  |  |  |  | my $term1 = 0.0; | 
| 683 | 0 |  |  |  |  |  | my ($i); | 
| 684 |  |  |  |  |  |  |  | 
| 685 | 0 | 0 | 0 |  |  |  | if ($R <= 0.09*$Ro) { | 
|  |  | 0 | 0 |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 686 | 0 |  |  |  |  |  | for ($i = 0; $i < 7; $i++) { | 
| 687 | 0 |  |  |  |  |  | $term1 = $term1 + $A[$i]*$R**$i; | 
| 688 |  |  |  |  |  |  | } | 
| 689 |  |  |  |  |  |  | } elsif ((0.09*$Ro < $R) && ($R <= 0.45*$Ro)) { | 
| 690 | 0 |  |  |  |  |  | for ($i = 0; $i < 6; $i++) { | 
| 691 | 0 |  |  |  |  |  | $term1 = $term1 + $B[$i]*$R**$i; | 
| 692 |  |  |  |  |  |  | } | 
| 693 |  |  |  |  |  |  | } elsif (((0.45*$Ro) <  $R) && ($R <= (1.6*$Ro))) { | 
| 694 | 0 |  |  |  |  |  | for ($i = 0; $i < 8; $i++) { | 
| 695 | 0 |  |  |  |  |  | $term1 = $term1 + $C[$i]*$R**$i; | 
| 696 |  |  |  |  |  |  | } | 
| 697 |  |  |  |  |  |  | }	elsif ((1.6*$Ro) < $R) { | 
| 698 | 0 |  |  |  |  |  | $term1 = $D0; | 
| 699 |  |  |  |  |  |  | } else { | 
| 700 | 0 |  |  |  |  |  | die "model_2 inconsistent\n"; | 
| 701 |  |  |  |  |  |  | } | 
| 702 |  |  |  |  |  |  |  | 
| 703 | 0 |  |  |  |  |  | return ($term1/$R); | 
| 704 |  |  |  |  |  |  | } | 
| 705 |  |  |  |  |  |  |  | 
| 706 |  |  |  |  |  |  | 1; | 
| 707 |  |  |  |  |  |  |  | 
| 708 |  |  |  |  |  |  | __DATA__ |