-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsdc.pl
More file actions
210 lines (165 loc) · 5.25 KB
/
jsdc.pl
File metadata and controls
210 lines (165 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/perl
# jsdc.pl
#
# Builds jsdc.stc file for Celestia
#
# Version 2.1 - LukeCEL (2020-02-23)
use Math::Trig;
use strict;
# default file paths
my $JSDC_PATH = 'diameters.csv';
my $STARS_PATH = 'stars.dat';
my $TXT_PATH = 'jsdc.stc';
# conversion constants
my $MAS_TO_DEG = 3600000;
my $LY_TO_KM = 9460730472580.8;
# data stored in these arrays
my %stars = (); # star details
ReadRadii();
ReadStars();
CheckStars();
WriteStc();
# ---------------------------- END OF MAIN PROGRAM --------------------------- #
# --------------------------- INPUT/OUTPUT FUNCTIONS ------------------------- #
# Read the Astrometric Catalogue into associative array
sub ReadRadii
{
print "Reading Cross-Matched Catalogues...\n";
local(*JSDCFILE);
if(!open(JSDCFILE, '<', $JSDC_PATH))
{
print " ERROR: Could not open $JSDC_PATH\n";
return;
}
my $numStars = 0;
while (my $curLine = <JSDCFILE>)
{
next if $. < 2;
chomp $curLine;
# split into separate fields using commas
my @fields = split(',', $curLine);
my $HIP = $fields[3];
my %star = (
'LDD' => $fields[32],
'e_LDD' => $fields[33],
);
$stars{$HIP} = {
'LDD' => $star{'LDD'},
'e_LDD' => $star{'e_LDD'},
'Dist' => ''
};
$numStars++;
}
close(JSDCFILE);
print " Read a total of $numStars records.\n";
}
sub ReadStars
{
print "Reading stars.dat file...\n";
open STARS, '<', $STARS_PATH or die "Cannot open stars.dat for reading.\n";
binmode STARS;
# read file header: test whether this is a star database and get number of stars
read(STARS, my $buf, 14);
my ($fileType, $version, $numStars) = unpack('A8SL', $buf);
die "Bad stars.dat format" if(($fileType ne 'CELSTARS') || ($version != 0x0100));
for (my $i = 0; $i < $numStars; $i++) {
read(STARS, $buf, 20);
my ($HIP, $x, $y, $z) = unpack('Lfffx4', $buf); # don't need magnitude or spectral type
if(exists $stars{$HIP}) {
$stars{$HIP}{'Dist'} = sqrt($x * $x + $y * $y + $z * $z);
}
}
close(STARSFILE);
print " Read a total of $numStars records.\n";
}
sub WriteStc
{
my $numStars = keys %stars;
print "Writing files...\n";
print " Writing text database to $TXT_PATH\n";
local(*TXTFILE);
open(TXTFILE, '>', $TXT_PATH) or die "ERROR: Could not write to $TXT_PATH\n";
# write file header
print TXTFILE "# Updated Catalogue of Stellar Radii for Celestia\n";
print TXTFILE "# Version 1.0 (2018-12-22)\n";
print TXTFILE "# LukeCEL, made from a script modified from one by Andrew Tribick\n";
print TXTFILE "#\n";
print TXTFILE "# Bourges, L et al. (2017), ASP 485, 223\n";
print TXTFILE "# The JMMC Stellar Diameters Catalog v2 (JSDC): A New Release Based on\n";
print TXTFILE "# SearchCal Improvements\n";
print TXTFILE "#\n";
print TXTFILE "# This catalogue was made using a Perl script, jsdc.pl. Stellar radii were\n";
print TXTFILE "# calculated from angular diameters and distances. Limb-darkened disk\n";
print TXTFILE "# diameters were taken from the JMMC Stellar Diameters Catalogue (JSDC v2.0)\n";
print TXTFILE "# and cross-matched with the Hipparcos Catalogue using the CDS XMATCH tool.\n";
print TXTFILE "# Distances were read from Celestia's binary-format star database\n";
print TXTFILE "# (stars.dat). Only diameters where the error is less than 3% of the\n";
print TXTFILE "# value itself are used.\n\n";
# write each star
foreach my $HIP (sort { $a <=> $b } keys %stars)
{
my $dist = $stars{$HIP}{'Dist'};
my $ldd = $stars{$HIP}{'LDD'};
my $e_ldd = $stars{$HIP}{'e_LDD'};
my $radius = AngularToPhysical($dist, $ldd);
print TXTFILE "Modify $HIP\n{\n\tRadius ";
print TXTFILE sprintf('%.0f', sprintf('%.4g', $radius));
print TXTFILE sprintf(" # Diameter = %s +/- %s mas\n}\n\n", $ldd, $e_ldd);
}
close(TXTFILE);
print " Wrote a total of $numStars stars.\n";
}
# -------------------------- DATA HANDLING ROUTINES -------------------------- #
# drop stars with bad data
sub CheckStars
{
print "Checking data...\n";
my $good = 0;
my $higherror = 0;
my $missingdist = 0;
foreach my $HIP (keys %stars)
{
# print "$HIP\n";
my $badness = TestDubious($stars{$HIP});
if ($badness == 0)
{
# good stars are fine
$good++;
}
elsif ($badness >= 1)
{
delete $stars{$HIP};
$higherror++;
# print "HIP $HIP\n";
}
}
print " $good stars with good data included.\n";
print " $higherror stars dropped.\n";
}
# reject stars
sub TestDubious
{
my $star = shift;
my $dubious = 0;
# if there is no distance information, we can't include this
$dubious = 1 if($star->{'Dist'} eq '');
# if there is no diameter information, we can't include this
$dubious = 2 if($star->{'LDD'} eq '');
# if diameter error is greater than 3 percent of the diameter, reject
if ($star->{'LDD'} ne '')
{
$dubious = 3 if(($star->{'e_LDD'} * 0.03 gt $star->{'LDD'}));
}
# otherwise the star is fine
return $dubious;
}
# ------------------------ ASTROPHYSICAL CALCULATIONS ------------------------ #
# convert angular diameter in milliarcseconds to physical radius in km
sub AngularToPhysical
{
my $dist = shift;
my $ldd = shift;
my $dist = $dist * $LY_TO_KM; # convert distance in ly to km
my $ldd = $ldd / $MAS_TO_DEG; # convert diameter in mas to degrees
return (tan(deg2rad($ldd)/2) * $dist);
}