1 // buildstardb.cpp
2 //
3 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9
10 #include <string>
11 #include <vector>
12 #include <map>
13 #include <algorithm>
14 #include <iostream>
15 #include <fstream>
16 #include <cstdio>
17 #include <assert.h>
18 #include "stardb.h"
19
20 using namespace std;
21
22
23 static string MainDatabaseFile("hip_main.dat");
24 static string ComponentDatabaseFile("h_dm_com.dat");
25 static string OrbitalDatabase("hip_dm_o.dat");
26
27 static const int HipStarRecordLength = 451;
28 static const int HipComponentRecordLength = 239;
29
30 static uint32 NullCCDMIdentifier = 0xffffffff;
31 static uint32 NullCatalogNumber = 0xffffffff;
32
33
34 class HipparcosStar
35 {
36 public:
37 HipparcosStar();
38
39 void write(ostream&);
40
41 uint32 HIPCatalogNumber;
42 uint32 HDCatalogNumber;
43 float ascension;
44 float declination;
45 float parallax;
46 float appMag;
47 StellarClass stellarClass;
48
49 uint32 CCDMIdentifier;
50 uint8 starsWithCCDM;
51 uint8 nComponents;
52 uint8 parallaxError;
53 };
54
HipparcosStar()55 HipparcosStar::HipparcosStar() :
56 HIPCatalogNumber(NullCatalogNumber),
57 HDCatalogNumber(NullCatalogNumber),
58 ascension(0.0f),
59 declination(0.0f),
60 parallax(0.0f),
61 appMag(0.0f),
62 CCDMIdentifier(NullCCDMIdentifier),
63 starsWithCCDM(0),
64 nComponents(1),
65 parallaxError(0)
66 {
67 }
68
binwrite(ostream & out,T x)69 template<class T> void binwrite(ostream& out, T x)
70 {
71 out.write(reinterpret_cast<char*>(&x), sizeof(T));
72 }
73
write(ostream & out)74 void HipparcosStar::write(ostream& out)
75 {
76 #if 0
77 if (HDCatalogNumber != NullCatalogNumber)
78 binwrite(out, HDCatalogNumber);
79 else
80 binwrite(out, HIPCatalogNumber | 0x10000000);
81 #endif
82 binwrite(out, HIPCatalogNumber);
83 binwrite(out, HDCatalogNumber);
84 binwrite(out, ascension);
85 binwrite(out, declination);
86 binwrite(out, parallax);
87 binwrite(out, (short) (appMag * 256));
88 binwrite(out, stellarClass);
89 binwrite(out, parallaxError);
90 }
91
operator <(const HipparcosStar & a,const HipparcosStar & b)92 bool operator<(const HipparcosStar& a, const HipparcosStar& b)
93 {
94 return a.HIPCatalogNumber < b.HIPCatalogNumber;
95 }
96
97 struct HIPCatalogComparePredicate
98 {
HIPCatalogComparePredicateHIPCatalogComparePredicate99 HIPCatalogComparePredicate() : dummy(0)
100 {
101 }
102
operator ()HIPCatalogComparePredicate103 bool operator()(const HipparcosStar* star0, const HipparcosStar* star1) const
104 {
105 return star0->HIPCatalogNumber < star1->HIPCatalogNumber;
106 }
107
operator ()HIPCatalogComparePredicate108 bool operator()(const HipparcosStar* star0, uint32 hip)
109 {
110 return star0->HIPCatalogNumber < hip;
111 }
112
113 int dummy;
114 };
115
116
117 class MultistarSystem
118 {
119 public:
120 int nStars; // Never greater than four in the HIPPARCOS catalog
121 HipparcosStar* stars[4];
122 };
123
124
125 class HipparcosComponent
126 {
127 public:
128 HipparcosComponent();
129
130 HipparcosStar* star;
131 char componentID;
132 char refComponentID;
133 float ascension;
134 float declination;
135 float appMag;
136 float bMag;
137 float vMag;
138 bool hasBV;
139 float positionAngle;
140 float separation;
141 };
142
HipparcosComponent()143 HipparcosComponent::HipparcosComponent() :
144 star(NULL),
145 componentID('A'),
146 refComponentID('A'),
147 appMag(0.0f),
148 bMag(0.0f),
149 vMag(0.0f),
150 hasBV(false),
151 positionAngle(0.0f),
152 separation(0.0f)
153 {
154 }
155
156
157 vector<HipparcosStar> stars;
158 vector<HipparcosStar> companions;
159 vector<HipparcosComponent> components;
160 vector<HipparcosStar*> starIndex;
161
162 typedef map<uint32, MultistarSystem*> MultistarSystemCatalog;
163 MultistarSystemCatalog starSystems;
164
165
findStar(uint32 hip)166 HipparcosStar* findStar(uint32 hip)
167 {
168 HIPCatalogComparePredicate pred;
169
170 vector<HipparcosStar*>::iterator iter = lower_bound(starIndex.begin(),
171 starIndex.end(),
172 hip, pred);
173 if (iter == starIndex.end())
174 return NULL;
175 HipparcosStar* star = *iter;
176 if (star->HIPCatalogNumber == hip)
177 return star;
178 else
179 return NULL;
180 }
181
182
ParseStellarClass(char * starType)183 StellarClass ParseStellarClass(char *starType)
184 {
185 StellarClass::StarType type = StellarClass::NormalStar;
186 StellarClass::SpectralClass specClass = StellarClass::Spectral_A;
187 StellarClass::LuminosityClass lum = StellarClass::Lum_V;
188 unsigned short number = 5;
189 int i = 0;
190
191 // Subdwarves (luminosity class VI) are prefixed with sd
192 if (starType[i] == 's' && starType[i + 1] == 'd')
193 {
194 lum = StellarClass::Lum_VI;
195 i += 2;
196 }
197
198 switch (starType[i])
199 {
200 case 'O':
201 specClass = StellarClass::Spectral_O;
202 break;
203 case 'B':
204 specClass = StellarClass::Spectral_B;
205 break;
206 case 'A':
207 specClass = StellarClass::Spectral_A;
208 break;
209 case 'F':
210 specClass = StellarClass::Spectral_F;
211 break;
212 case 'G':
213 specClass = StellarClass::Spectral_G;
214 break;
215 case 'K':
216 specClass = StellarClass::Spectral_K;
217 break;
218 case 'M':
219 specClass = StellarClass::Spectral_M;
220 break;
221 case 'R':
222 specClass = StellarClass::Spectral_R;
223 break;
224 case 'N':
225 specClass = StellarClass::Spectral_S;
226 break;
227 case 'S':
228 specClass = StellarClass::Spectral_N;
229 break;
230 case 'W':
231 i++;
232 if (starType[i] == 'C')
233 specClass = StellarClass::Spectral_WC;
234 else if (starType[i] == 'N')
235 specClass = StellarClass::Spectral_WN;
236 else
237 i--;
238 break;
239
240 case 'D':
241 type = StellarClass::WhiteDwarf;
242 return StellarClass(type, specClass, 0, lum);
243
244 default:
245 specClass = StellarClass::Spectral_Unknown;
246 break;
247 }
248
249 i++;
250 if (starType[i] >= '0' && starType[i] <= '9')
251 {
252 number = starType[i] - '0';
253 }
254 else
255 {
256 // No number given for spectral class; assume it's a 5 unless
257 // the star is type O, as O5 stars are exceedingly rare.
258 if (specClass == StellarClass::Spectral_O)
259 number = 9;
260 else
261 number = 5;
262 }
263
264 if (lum != StellarClass::Lum_VI)
265 {
266 i++;
267 lum = StellarClass::Lum_V;
268 while (i < 13 && starType[i] != '\0') {
269 if (starType[i] == 'I') {
270 if (starType[i + 1] == 'I') {
271 if (starType[i + 2] == 'I') {
272 lum = StellarClass::Lum_III;
273 } else {
274 lum = StellarClass::Lum_II;
275 }
276 } else if (starType[i + 1] == 'V') {
277 lum = StellarClass::Lum_IV;
278 } else if (starType[i + 1] == 'a') {
279 if (starType[i + 2] == '0')
280 lum = StellarClass::Lum_Ia0;
281 else
282 lum = StellarClass::Lum_Ia;
283 } else if (starType[i + 1] == 'b') {
284 lum = StellarClass::Lum_Ib;
285 } else {
286 lum = StellarClass::Lum_Ib;
287 }
288 break;
289 } else if (starType[i] == 'V') {
290 if (starType[i + 1] == 'I')
291 lum = StellarClass::Lum_VI;
292 else
293 lum = StellarClass::Lum_V;
294 break;
295 }
296 i++;
297 }
298 }
299
300 return StellarClass(type, specClass, number, lum);
301 }
302
303
TheSun()304 HipparcosStar TheSun()
305 {
306 HipparcosStar star;
307
308 star.HDCatalogNumber = 0;
309 star.HIPCatalogNumber = 0;
310 star.ascension = 0.0f;
311 star.declination = 0.0f;
312 star.parallax = 1000000.0f;
313 star.appMag = -15.17f;
314 star.stellarClass = StellarClass(StellarClass::NormalStar,
315 StellarClass::Spectral_G, 2,
316 StellarClass::Lum_V);
317
318 return star;
319 }
320
321
ReadStarRecord(istream & in)322 bool ReadStarRecord(istream& in)
323 {
324 HipparcosStar star;
325 char buf[HipStarRecordLength];
326
327 in.read(buf, HipStarRecordLength);
328
329 if (sscanf(buf + 2, "%d", &star.HIPCatalogNumber) != 1)
330 {
331 cout << "Error reading catalog number.\n";
332 return false;
333 }
334
335 sscanf(buf + 390, "%d", &star.HDCatalogNumber);
336
337 if (sscanf(buf + 41, "%f", &star.appMag) != 1)
338 {
339 cout << "Error reading magnitude.\n";
340 return false;
341 }
342
343 if (sscanf(buf + 79, "%f", &star.parallax) != 1)
344 {
345 // cout << "Error reading parallax.\n";
346 }
347
348 bool coordReadError = false;
349 if (sscanf(buf + 51, "%f", &star.ascension) != 1)
350 coordReadError = true;
351 if (sscanf(buf + 64, "%f", &star.declination) != 1)
352 coordReadError = true;
353 star.ascension = (float) (star.ascension * 24.0 / 360.0);
354
355 // Read the lower resolution coordinates in hhmmss form if we failed
356 // to read the coordinates in degrees. Not sure why the high resolution
357 // coordinates are occasionally missing . . .
358 if (coordReadError)
359 {
360 int hh = 0;
361 int mm = 0;
362 float seconds;
363 if (sscanf(buf + 17, "%d %d %f", &hh, &mm, &seconds) != 3)
364 {
365 cout << "Error reading ascension.\n";
366 return false;
367 }
368 star.ascension = hh + (float) mm / 60.0f + (float) seconds / 3600.0f;
369
370 char decSign;
371 int deg;
372 if (sscanf(buf + 29, "%c%d %d %f", &decSign, °, &mm, &seconds) != 4)
373 {
374 cout << "Error reading declination.\n";
375 return false;
376 }
377 star.declination = deg + (float) mm / 60.0f + (float) seconds / 3600.0f;
378 if (decSign == '-')
379 star.declination = -star.declination;
380 }
381
382 char* spectralType = buf + 435;
383 spectralType[12] = '\0';
384 star.stellarClass = ParseStellarClass(spectralType);
385
386 int asc = 0;
387 int dec = 0;
388 char decSign = ' ';
389 if (sscanf(buf + 327, "%d%c%d", &asc, &decSign, &dec) == 3)
390 {
391 if (decSign == '-')
392 dec = -dec;
393 star.CCDMIdentifier = asc << 16 | (dec & 0xffff);
394
395 int n = 1;
396 sscanf(buf + 340, "%d", &n);
397 star.starsWithCCDM = (uint8) n;
398 sscanf(buf + 343, "%d", &n);
399 star.nComponents = (uint8) n;
400 }
401
402 float parallaxError = 0.0f;
403 if (sscanf(buf + 119, "%f", ¶llaxError) != 0)
404 {
405 if (star.parallax < 0.0f || parallaxError / star.parallax > 1.0f)
406 star.parallaxError = (int8) 255;
407 else
408 star.parallaxError = (int8) (parallaxError / star.parallax * 200);
409 }
410
411 stars.insert(stars.end(), star);
412
413 return true;
414 }
415
416
ReadComponentRecord(istream & in)417 bool ReadComponentRecord(istream& in)
418 {
419 HipparcosComponent component;
420 char buf[HipComponentRecordLength];
421
422 in.read(buf, HipComponentRecordLength);
423
424 uint32 hip;
425 if (sscanf(buf + 42, "%ud", &hip) != 1)
426 {
427 cout << "Missing HIP catalog number for component.\n";
428 return false;
429 }
430
431 component.star = findStar(hip);
432 if (component.star == NULL)
433 {
434 cout << "Nonexistent HIP catalog number for component.\n";
435 return false;
436 }
437
438 if (sscanf(buf + 40, "%c", &component.componentID) != 1)
439 {
440 cout << "Missing component identifier.\n";
441 return false;
442 }
443
444 if (sscanf(buf + 175, "%c", &component.refComponentID) != 1)
445 {
446 cout << "Error reading reference component.\n";
447 return false;
448 }
449 if (component.refComponentID == ' ')
450 component.refComponentID = component.componentID;
451
452 // Read astrometric information
453 if (sscanf(buf + 88, "%f", &component.ascension) != 1)
454 {
455 cout << "Missing ascension for component.\n";
456 return false;
457 }
458 component.ascension = (float) (component.ascension * 24.0 / 360.0);
459
460 if (sscanf(buf + 101, "%f", &component.declination) != 1)
461 {
462 cout << "Missing declination for component.\n";
463 return false;
464 }
465
466 // Read photometric information
467 if (sscanf(buf + 49, "%f", &component.appMag) != 1)
468 {
469 cout << "Missing magnitude for component.\n";
470 return false;
471 }
472
473 // vMag and bMag may be necessary to guess the spectral type
474 if (sscanf(buf + 62, "%f", &component.bMag) != 1 ||
475 sscanf(buf + 69, "%f", &component.vMag) != 1)
476 {
477 component.bMag = component.vMag = component.appMag;
478 }
479 else
480 {
481 component.hasBV = true;
482 }
483
484 if (component.componentID != component.refComponentID)
485 {
486 if (sscanf(buf + 177, "%f", &component.positionAngle) != 1)
487 {
488 cout << "Missing position angle for component.\n";
489 return false;
490 }
491 if (sscanf(buf + 185, "%f", &component.separation) != 1)
492 {
493 cout << "Missing separation for component.\n";
494 return false;
495 }
496 }
497
498 components.insert(components.end(), component);
499
500 return true;
501 };
502
503
BuildMultistarSystemCatalog()504 void BuildMultistarSystemCatalog()
505 {
506 for (vector<HipparcosStar>::iterator iter = stars.begin();
507 iter != stars.end(); iter++)
508 {
509 if (iter->CCDMIdentifier != NullCCDMIdentifier)
510 {
511 MultistarSystemCatalog::iterator it =
512 starSystems.find(iter->CCDMIdentifier);
513 if (it == starSystems.end())
514 {
515 MultistarSystem* multiSystem = new MultistarSystem();
516 multiSystem->nStars = 1;
517 multiSystem->stars[0] = iter;
518 starSystems.insert(MultistarSystemCatalog::value_type(iter->CCDMIdentifier, multiSystem));
519 }
520 else
521 {
522 MultistarSystem* multiSystem = it->second;
523 if (multiSystem->nStars == 4)
524 {
525 cout << "Number of stars in system exceeds 4\n";
526 }
527 else
528 {
529 multiSystem->stars[multiSystem->nStars] = iter;
530 multiSystem->nStars++;
531 }
532 }
533 }
534 }
535 }
536
537
guessSpectralType(float colorIndex,float absMag)538 StellarClass guessSpectralType(float colorIndex, float absMag)
539 {
540 StellarClass::SpectralClass specClass = StellarClass::Spectral_Unknown;
541 float subclass = 0.0f;
542
543 if (colorIndex < -0.25f)
544 {
545 specClass = StellarClass::Spectral_O;
546 subclass = (colorIndex + 0.5f) / 0.25f;
547 }
548 else if (colorIndex < 0.0f)
549 {
550 specClass = StellarClass::Spectral_B;
551 subclass = (colorIndex + 0.25f) / 0.25f;
552 }
553 else if (colorIndex < 0.25f)
554 {
555 specClass = StellarClass::Spectral_A;
556 subclass = (colorIndex - 0.0f) / 0.25f;
557 }
558 else if (colorIndex < 0.6f)
559 {
560 specClass = StellarClass::Spectral_F;
561 subclass = (colorIndex - 0.25f) / 0.35f;
562 }
563 else if (colorIndex < 0.85f)
564 {
565 specClass = StellarClass::Spectral_G;
566 subclass = (colorIndex - 0.6f) / 0.25f;
567 }
568 else if (colorIndex < 1.4f)
569 {
570 specClass = StellarClass::Spectral_K;
571 subclass = (colorIndex - 0.85f) / 0.55f;
572 }
573 else
574 {
575 specClass = StellarClass::Spectral_M;
576 subclass = (colorIndex - 1.4f) / 1.0f;
577 }
578
579 if (subclass < 0.0f)
580 subclass = 0.0f;
581 else if (subclass > 1.0f)
582 subclass = 1.0f;
583
584 return StellarClass(StellarClass::NormalStar,
585 specClass,
586 (unsigned int) (subclass * 9.99f),
587 StellarClass::Lum_V);
588 }
589
590
ConstrainComponentParallaxes()591 void ConstrainComponentParallaxes()
592 {
593 for (MultistarSystemCatalog::iterator iter = starSystems.begin();
594 iter != starSystems.end(); iter++)
595 {
596 MultistarSystem* multiSystem = iter->second;
597 if (multiSystem->nStars > 1)
598 {
599 for (int i = 1; i < multiSystem->nStars; i++)
600 multiSystem->stars[i]->parallax = multiSystem->stars[0]->parallax;
601 }
602 #if 0
603 if (multiSystem->nStars > 2)
604 {
605 cout << multiSystem->nStars << ": ";
606 if (multiSystem->stars[0]->HDCatalogNumber != NullCatalogNumber)
607 cout << "HD " << multiSystem->stars[0]->HDCatalogNumber;
608 else
609 cout << "HIP " << multiSystem->stars[0]->HIPCatalogNumber;
610 cout << '\n';
611 }
612 #endif
613 }
614 }
615
616
CorrectErrors()617 void CorrectErrors()
618 {
619 for (vector<HipparcosStar>::iterator iter = stars.begin();
620 iter != stars.end(); iter++)
621 {
622 // Fix the spectral class of Capella, listed for some reason
623 // as M1 in the database.
624 if (iter->HDCatalogNumber == 34029)
625 {
626 iter->stellarClass = StellarClass(StellarClass::NormalStar,
627 StellarClass::Spectral_G, 0,
628 StellarClass::Lum_III);
629 }
630 }
631 }
632
633
634 // Process the vector of star components and insert those that are companions
635 // of stars in the primary database into the companions vector.
CreateCompanionList()636 void CreateCompanionList()
637 {
638 for (vector<HipparcosComponent>::iterator iter = components.begin();
639 iter != components.end(); iter++)
640 {
641 // Don't insert the reference component, as this star should already
642 // be in the primary database.
643 if (iter->componentID != iter->refComponentID)
644 {
645 int componentNumber = iter->componentID - 'A';
646 if (componentNumber > 0 && componentNumber < 8)
647 {
648 HipparcosStar star;
649
650 star.HDCatalogNumber = NullCatalogNumber;
651 star.HIPCatalogNumber = iter->star->HIPCatalogNumber |
652 (componentNumber << 25);
653
654 star.ascension = iter->ascension;
655 star.declination = iter->declination;
656 star.parallax = iter->star->parallax;
657 star.appMag = iter->appMag;
658 if (iter->hasBV)
659 star.stellarClass = guessSpectralType(iter->bMag - iter->vMag, 0.0f);
660 else
661 star.stellarClass = StellarClass(StellarClass::NormalStar,
662 StellarClass::Spectral_Unknown,
663 0, StellarClass::Lum_V);
664
665 star.CCDMIdentifier = iter->star->CCDMIdentifier;
666 star.parallaxError = iter->star->parallaxError;
667
668 companions.insert(companions.end(), star);
669 }
670 }
671 }
672 }
673
674
ShowStarsWithComponents()675 void ShowStarsWithComponents()
676 {
677 cout << "\nStars with >2 components\n";
678 for (vector<HipparcosStar>::iterator iter = stars.begin();
679 iter != stars.end(); iter++)
680 {
681 if (iter->nComponents > 2)
682 {
683 cout << (int) iter->nComponents << ": ";
684 if (iter->HDCatalogNumber != NullCatalogNumber)
685 cout << "HD " << iter->HDCatalogNumber;
686 else
687 cout << "HIP " << iter->HIPCatalogNumber;
688 cout << '\n';
689 }
690 }
691 }
692
693
main(int argc,char * argv[])694 int main(int argc, char* argv[])
695 {
696 assert(sizeof(StellarClass) == 2);
697
698 // Read star records from the primary HIPPARCOS catalog
699 {
700 ifstream mainDatabase(MainDatabaseFile.c_str(), ios::in | ios::binary);
701 if (!mainDatabase.good())
702 {
703 cout << "Error opening " << MainDatabaseFile << '\n';
704 exit(1);
705 }
706
707 cout << "Reading HIPPARCOS data set.\n";
708 while (mainDatabase.good())
709 {
710 ReadStarRecord(mainDatabase);
711 if (stars.size() % 10000 == 0)
712 cout << stars.size() << " records.\n";
713 }
714 }
715 cout << "Read " << stars.size() << " stars from main database.\n";
716
717 cout << "Adding the Sun...\n";
718 stars.insert(stars.end(), TheSun());
719
720 cout << "Sorting stars...\n";
721 {
722 starIndex.reserve(stars.size());
723 for (vector<HipparcosStar>::iterator iter = stars.begin();
724 iter != stars.end(); iter++)
725 {
726 starIndex.insert(starIndex.end(), iter);
727 }
728
729 HIPCatalogComparePredicate pred;
730
731 // It may not even be necessary to sort the records, if the
732 // HIPPARCOS catalog is strictly ordered by catalog number. I'm not
733 // sure about this however,
734 random_shuffle(starIndex.begin(), starIndex.end());
735 sort(starIndex.begin(), starIndex.end(), pred);
736 }
737
738 // Read component records
739 {
740 ifstream componentDatabase(ComponentDatabaseFile.c_str(),
741 ios::in | ios::binary);
742 if (!componentDatabase.good())
743 {
744 cout << "Error opening " << ComponentDatabaseFile << '\n';
745 exit(1);
746 }
747
748 cout << "Reading HIPPARCOS component database.\n";
749 while (componentDatabase.good())
750 {
751 ReadComponentRecord(componentDatabase);
752 }
753 }
754 cout << "Read " << components.size() << " components.\n";
755
756 {
757 int aComp = 0, bComp = 0, cComp = 0, dComp = 0, eComp = 0, otherComp = 0;
758 int bvComp = 0;
759 for (int i = 0; i < components.size(); i++)
760 {
761 switch (components[i].componentID)
762 {
763 case 'A':
764 aComp++; break;
765 case 'B':
766 bComp++; break;
767 case 'C':
768 cComp++; break;
769 case 'D':
770 dComp++; break;
771 case 'E':
772 eComp++; break;
773 default:
774 otherComp++; break;
775 }
776 if (components[i].hasBV && components[i].componentID != 'A')
777 bvComp++;
778 }
779
780 cout << "A:" << aComp << " B:" << bComp << " C:" << cComp << " D:" << dComp << " E:" << eComp << '\n';
781 cout << "Components with B-V mag: " << bvComp << '\n';
782 }
783
784 cout << "Building catalog of multiple star systems.\n";
785 BuildMultistarSystemCatalog();
786
787 int nMultipleSystems = starSystems.size();
788 cout << "Stars in multiple star systems: " << nMultipleSystems << '\n';
789
790 ConstrainComponentParallaxes();
791
792 CorrectErrors();
793
794 // CreateCompanionList();
795 cout << "Companion stars: " << companions.size() << '\n';
796 cout << "Total stars: " << stars.size() + companions.size() << '\n';
797
798 ShowStarsWithComponents();
799
800 char* outputFile = "stars.dat";
801 if (argc > 1)
802 outputFile = argv[1];
803
804 cout << "Writing processed star records to " << outputFile << '\n';
805 ofstream out(outputFile, ios::out | ios::binary);
806 if (!out.good())
807 {
808 cout << "Error opening " << outputFile << '\n';
809 exit(1);
810 }
811
812 binwrite(out, stars.size() + companions.size());
813 {
814 vector<HipparcosStar>::iterator iter;
815 for (iter = stars.begin(); iter != stars.end(); iter++)
816 iter->write(out);
817 for (iter = companions.begin(); iter != companions.end(); iter++)
818 iter->write(out);
819 }
820
821 #if 0
822 char* hdOutputFile = "hdxref.dat";
823
824 cout << "Writing out HD cross reference to " << hdOutputFile << '\n';
825 ofstream hdout(hdOutputFile, ios::out | ios::binary);
826 if (!out.good())
827 {
828 cout << "Error opening " << hdOutputFile << '\n';
829 exit(1);
830 }
831
832 {
833 int nHD = 0;
834 vector<HipparcosStar>::iterator iter;
835 for (iter = stars.begin(); iter != stars.end(); iter++)
836 {
837 if (iter->HDCatalogNumber != NullCatalogNumber)
838 nHD++;
839 }
840 binwrite(hdout, nHD);
841
842 cout << nHD << " stars have HD numbers.\n";
843
844 for (iter = stars.begin(); iter != stars.end(); iter++)
845 {
846 if (iter->HDCatalogNumber != NullCatalogNumber)
847 {
848 binwrite(hdout, iter->HDCatalogNumber);
849 binwrite(hdout, iter->HIPCatalogNumber);
850 }
851 }
852 }
853 #endif
854
855 return 0;
856 }
857