1 /*
2 # This file is part of the Astrometry.net suite.
3 # Licensed under a 3-clause BSD style license - see LICENSE
4 */
5 #include <math.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <unistd.h>
11 #include <zlib.h>
12
13 #include "2mass.h"
14 #include "2mass-fits.h"
15 #include "healpix.h"
16 #include "starutil.h"
17 #include "boilerplate.h"
18 #include "fitsioutils.h"
19
20 #define OPTIONS "ho:N:"
21
print_help(char * progname)22 void print_help(char* progname) {
23 BOILERPLATE_HELP_HEADER(stdout);
24 printf("usage:\n"
25 " %s -o <output-filename-template>\n"
26 " [-N <healpix-nside>] (default = 8.)\n"
27 " <input-file> [<input-file> ...]\n"
28 "\n"
29 "Input files are gzipped 2MASS PSC catalog files, named like psc_aaa.gz."
30 "\n", progname);
31 }
32
33
main(int argc,char ** args)34 int main(int argc, char** args) {
35 int c;
36 char* outfn = NULL;
37 int startoptind;
38 int Nside = 8;
39 int HP;
40 int i;
41
42 twomass_fits** cats;
43
44 while ((c = getopt(argc, args, OPTIONS)) != -1) {
45 switch (c) {
46 case '?':
47 case 'h':
48 print_help(args[0]);
49 exit(0);
50 case 'N':
51 Nside = atoi(optarg);
52 break;
53 case 'o':
54 outfn = optarg;
55 break;
56 }
57 }
58
59 if (!outfn || (optind == argc)) {
60 print_help(args[0]);
61 exit(-1);
62 }
63
64 if (Nside < 1) {
65 fprintf(stderr, "Nside must be >= 1.\n");
66 print_help(args[0]);
67 exit(-1);
68 }
69
70 HP = 12 * Nside * Nside;
71 cats = calloc((size_t)HP, sizeof(twomass_fits*));
72
73 printf("Nside = %i, using %i healpixes.\n", Nside, HP);
74
75 printf("Reading 2MASS files... ");
76 fflush(stdout);
77
78 startoptind = optind;
79 for (; optind<argc; optind++) {
80 char* infn;
81 gzFile fiz = NULL;
82 char line[1024];
83 int nentries;
84
85 infn = args[optind];
86 printf("\nReading file %i of %i: %s\n", 1 + optind - startoptind,
87 argc - startoptind, infn);
88 infn = args[optind];
89 fiz = gzopen(infn, "rb");
90 if (!fiz) {
91 fprintf(stderr, "Failed to open file %s: %s\n", infn, strerror(errno));
92 exit(-1);
93 }
94 nentries = 0;
95 for (;;) {
96 twomass_entry e;
97 int hp;
98
99 if (gzeof(fiz))
100 break;
101
102 if (gzgets(fiz, line, 1024) == Z_NULL) {
103 if (gzeof(fiz))
104 break;
105 fprintf(stderr, "Failed to read a line from file %s: %s\n", infn, strerror(errno));
106 exit(-1);
107 }
108
109 if (twomass_parse_entry(&e, line)) {
110 fprintf(stderr, "Failed to parse 2MASS entry from file %s.\n", infn);
111 exit(-1);
112 }
113
114 hp = radectohealpix(deg2rad(e.ra), deg2rad(e.dec), Nside);
115 if (!cats[hp]) {
116 char fn[256];
117 qfits_header* hdr;
118
119 sprintf(fn, outfn, hp);
120 cats[hp] = twomass_fits_open_for_writing(fn);
121 if (!cats[hp]) {
122 fprintf(stderr, "Failed to open 2MASS catalog for writing to file %s (hp %i).\n", fn, hp);
123 exit(-1);
124 }
125 // header remarks...
126 hdr = twomass_fits_get_primary_header(cats[hp]);
127 BOILERPLATE_ADD_FITS_HEADERS(hdr);
128 fits_header_add_int(hdr, "HEALPIX", hp, "The healpix number of this catalog.");
129 fits_header_add_int(hdr, "NSIDE", Nside, "The healpix resolution.");
130
131 fits_add_long_comment(hdr, "The fields are as described in the 2MASS documentation:");
132 fits_add_long_comment(hdr, " ftp://ftp.ipac.caltech.edu/pub/2mass/allsky/format_psc.html");
133 fits_add_long_comment(hdr, "with a few exceptions:");
134 fits_add_long_comment(hdr, "* all angular fields are measured in degrees");
135 fits_add_long_comment(hdr, "* the photometric quality flag values are:");
136 fits_add_long_comment(hdr, " %i: 'X' in 2MASS, No brightness info available.", TWOMASS_QUALITY_NO_BRIGHTNESS);
137 fits_add_long_comment(hdr, " %i: 'U' in 2MASS, The brightness val is an upper bound.", TWOMASS_QUALITY_UPPER_LIMIT_MAG);
138 fits_add_long_comment(hdr, " %i: 'F' in 2MASS, No magnitude sigma is available", TWOMASS_QUALITY_NO_SIGMA);
139 fits_add_long_comment(hdr, " %i: 'E' in 2MASS, Profile-fit photometry was bad", TWOMASS_QUALITY_BAD_FIT);
140 fits_add_long_comment(hdr, " %i: 'A' in 2MASS, Best quality", TWOMASS_QUALITY_A);
141 fits_add_long_comment(hdr, " %i: 'B' in 2MASS, ...", TWOMASS_QUALITY_B);
142 fits_add_long_comment(hdr, " %i: 'C' in 2MASS, ...", TWOMASS_QUALITY_C);
143 fits_add_long_comment(hdr, " %i: 'D' in 2MASS, Worst quality", TWOMASS_QUALITY_D);
144 fits_add_long_comment(hdr, "* the confusion/contamination flag values are:");
145 fits_add_long_comment(hdr, " %i: '0' in 2MASS, No problems.", TWOMASS_CC_NONE);
146 fits_add_long_comment(hdr, " %i: 'p' in 2MASS, Persistence.", TWOMASS_CC_PERSISTENCE);
147 fits_add_long_comment(hdr, " %i: 'c' in 2MASS, Confusion.", TWOMASS_CC_CONFUSION);
148 fits_add_long_comment(hdr, " %i: 'd' in 2MASS, Diffraction.", TWOMASS_CC_DIFFRACTION);
149 fits_add_long_comment(hdr, " %i: 's' in 2MASS, Stripe.", TWOMASS_CC_STRIPE);
150 fits_add_long_comment(hdr, " %i: 'b' in 2MASS, Band merge.", TWOMASS_CC_BANDMERGE);
151 fits_add_long_comment(hdr, "* the association flag values are:");
152 fits_add_long_comment(hdr, " %i: none.", TWOMASS_ASSOCIATION_NONE);
153 fits_add_long_comment(hdr, " %i: Tycho.", TWOMASS_ASSOCIATION_TYCHO);
154 fits_add_long_comment(hdr, " %i: USNO A-2.", TWOMASS_ASSOCIATION_USNOA2);
155 fits_add_long_comment(hdr, "* the NULL value for floats is %f", TWOMASS_NULL);
156 fits_add_long_comment(hdr, "* the NULL value for the 'ext_key' aka 'xsc_key' field is");
157 fits_add_long_comment(hdr, " %i (0x%x).", TWOMASS_KEY_NULL, TWOMASS_KEY_NULL);
158
159 if (twomass_fits_write_headers(cats[hp])) {
160 fprintf(stderr, "Failed to write 2MASS catalog headers: %s\n", fn);
161 exit(-1);
162 }
163 }
164 if (twomass_fits_write_entry(cats[hp], &e)) {
165 fprintf(stderr, "Failed to write 2MASS catalog entry.\n");
166 exit(-1);
167 }
168
169 nentries++;
170 if (!(nentries % 100000)) {
171 printf(".");
172 fflush(stdout);
173 }
174 }
175 gzclose(fiz);
176 printf("\n");
177
178 printf("Read %i entries.\n", nentries);
179 }
180
181 printf("Finishing up...\n");
182 for (i=0; i<HP; i++) {
183 if (!cats[i])
184 continue;
185 if (twomass_fits_fix_headers(cats[i]) ||
186 twomass_fits_close(cats[i])) {
187 fprintf(stderr, "Failed to close 2MASS catalog.\n");
188 exit(-1);
189 }
190 }
191 free(cats);
192 printf("Done!\n");
193
194 return 0;
195 }
196
197