File Coverage

blib/lib/Astro/Misc.pm
Criterion Covered Total %
statement 35 279 12.5
branch 0 104 0.0
condition 0 21 0.0
subroutine 11 21 52.3
pod 7 10 70.0
total 53 435 12.1


line stmt bran cond sub pod time code
1             package Astro::Misc;
2 1     1   382 use strict;
  1         1  
  1         29  
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   3 use Exporter ();
  1         1  
  1         14  
31 1         96 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL
32 1     1   2 $Temp $parsecAU $au2km $G $c @ThompsonData);
  1         1  
33 1     1   4 $VERSION = '1.01';
34 1         7 @ISA = qw(Exporter);
35              
36 1         2 @EXPORT = qw( read_possm calc_U calc_Nl lum2spectral
37             Nl2spectral kindist);
38 1         1 @EXPORT_OK = qw ( $Temp read_lovas a model_1 model_2 @ThompsonData $c);
39 1         30 @EXPORT_FAIL = qw ( );
40              
41 1     1   3 use Carp;
  1         1  
  1         37  
42 1     1   3 use POSIX qw( asin log10);
  1         1  
  1         4  
43              
44 1     1   42 use Astro::Time qw( $PI );
  1         10  
  1         68  
45 1     1   3 use Astro::Coord qw( fk5fk4 fk4gal );
  1         0  
  1         42  
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   3 use constant SPEC => 0;
  1         1  
  1         35  
58 1     1   3 use constant LUM => 2;
  1         1  
  1         54  
59 1     1   5 use constant NL => 5;
  1         1  
  1         1940  
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__