File indexing completed on 2024-09-08 03:28:58
0001 /* 0002 SPDX-FileCopyrightText: 2008 Akarsh Simha <akarshsimha@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <stdio.h> 0008 #include <stdlib.h> 0009 #include <math.h> 0010 #include <sys/types.h> 0011 #include <string.h> 0012 #include "byteorder.h" 0013 0014 #define HTM_LEVEL 3 0015 #define INDEX_ENTRY_SIZE 12 0016 0017 #include "binfile.h" 0018 0019 /* 0020 * struct to store star data, to be written in this format, into the binary file. 0021 */ 0022 0023 typedef struct starData 0024 { 0025 int32_t RA; 0026 int32_t Dec; 0027 int32_t dRA; 0028 int32_t dDec; 0029 int32_t parallax; 0030 int32_t HD; 0031 int16_t mag; 0032 int16_t bv_index; 0033 char spec_type[2]; 0034 char flags; 0035 char unused; 0036 } starData; 0037 0038 dataElement de[100]; 0039 u_int16_t nfields; 0040 long index_offset, data_offset; 0041 char byteswap; 0042 u_int32_t ntrixels; 0043 0044 /* 0045 * Does byteswapping for starData structures 0046 */ 0047 void bswap_stardata(starData *stardata) 0048 { 0049 stardata->RA = bswap_32(stardata->RA); 0050 stardata->Dec = bswap_32(stardata->Dec); 0051 stardata->dRA = bswap_32(stardata->dRA); 0052 stardata->dDec = bswap_32(stardata->dDec); 0053 stardata->parallax = bswap_32(stardata->parallax); 0054 stardata->HD = bswap_32(stardata->HD); 0055 stardata->mag = bswap_16(stardata->mag); 0056 stardata->bv_index = bswap_16(stardata->bv_index); 0057 } 0058 0059 int verifyIndexValidity(FILE *f) 0060 { 0061 int i; 0062 u_int32_t trixel; 0063 u_int32_t offset; 0064 u_int32_t prev_offset; 0065 u_int32_t nrecs; 0066 u_int32_t prev_nrecs; 0067 unsigned int nerr; 0068 0069 fprintf(stdout, "Performing Index Table Validity Check...\n"); 0070 fprintf(stdout, "Assuming that index starts at %X\n", ftell(f)); 0071 index_offset = ftell(f); 0072 0073 prev_offset = 0; 0074 prev_nrecs = 0; 0075 nerr = 0; 0076 0077 for (i = 0; i < ntrixels; ++i) 0078 { 0079 if (!fread(&trixel, 4, 1, f)) 0080 { 0081 fprintf(stderr, "Table truncated before expected! Read i = %d records so far\n", i); 0082 +nerr; 0083 break; 0084 } 0085 if (byteswap) 0086 trixel = bswap_32(trixel); 0087 if (trixel >= ntrixels) 0088 { 0089 fprintf(stderr, "Trixel number %u is greater than the expected number of trixels %u\n", trixel, ntrixels); 0090 ++nerr; 0091 } 0092 if (trixel != i) 0093 { 0094 fprintf(stderr, "Found trixel = %d, while I expected number = %d\n", trixel, i); 0095 ++nerr; 0096 } 0097 fread(&offset, 4, 1, f); 0098 if (byteswap) 0099 offset = bswap_32(offset); 0100 fread(&nrecs, 4, 1, f); 0101 if (byteswap) 0102 nrecs = bswap_32(nrecs); 0103 if (prev_offset != 0 && prev_nrecs != (-prev_offset + offset) / sizeof(starData)) 0104 { 0105 fprintf(stderr, "Expected %u = (%X - %x) / %d records, but found %u, in trixel %d\n", 0106 (offset - prev_offset) / sizeof(starData), offset, prev_offset, sizeof(starData), nrecs, trixel); 0107 ++nerr; 0108 } 0109 prev_offset = offset; 0110 prev_nrecs = nrecs; 0111 } 0112 0113 data_offset = ftell(f); 0114 0115 if (nerr) 0116 { 0117 fprintf(stderr, "ERROR ;-): The index seems to have %u errors\n", nerr); 0118 } 0119 else 0120 { 0121 fprintf(stdout, "Index verified. PASSED.\n"); 0122 } 0123 } 0124 0125 /** 0126 *This method ensures that the data part of the file is sane. It ensures that there are no jumps in magnitude etc. 0127 */ 0128 int verifyStarData(FILE *f) 0129 { 0130 int16_t faintMag; 0131 int8_t HTM_Level; 0132 u_int16_t MSpT; 0133 int16_t realFaintMag = -500; 0134 u_int16_t realMSpT; 0135 u_int32_t nstars; 0136 u_int32_t offset; 0137 0138 int trixel, i; 0139 int nerr_trixel; 0140 int nerr; 0141 0142 starData data; 0143 int16_t mag; 0144 0145 fprintf(stdout, "Assuming that the data starts at %ld\n", ftell(f)); 0146 fread(&faintMag, 2, 1, f); 0147 fprintf(stdout, "Faint Magnitude Limit: %f\n", faintMag / 100.0); 0148 fread(&HTM_Level, 1, 1, f); 0149 fprintf(stdout, "HTMesh Level: %d\n", HTM_Level); 0150 if (HTM_Level != HTM_LEVEL) 0151 { 0152 fprintf(stderr, 0153 "ERROR: HTMesh Level in file (%d) and HTM_LEVEL in program (%d) differ. Please set the define " 0154 "directive for HTM_LEVEL correctly and rebuild\n.", 0155 HTM_Level, HTM_LEVEL); 0156 return 0; 0157 } 0158 fread(&MSpT, 2, 1, f); 0159 0160 mag = -500; 0161 nerr = 0; 0162 0163 // Scan the file for magnitude jumps, etc. 0164 realMSpT = 0; 0165 for (trixel = 0; trixel < ntrixels; ++trixel) 0166 { 0167 mag = -500; 0168 nerr_trixel = 0; 0169 fprintf(stdout, "Checking trixel #%d: ", trixel); 0170 fseek(f, index_offset + trixel * INDEX_ENTRY_SIZE + 4, SEEK_SET); 0171 fread(&offset, 4, 1, f); 0172 fread(&nstars, 4, 1, f); 0173 if (nstars > realMSpT) 0174 realMSpT = nstars; 0175 fseek(f, offset, SEEK_SET); 0176 for (i = 0; i < nstars; ++i) 0177 { 0178 fread(&data, sizeof(starData), 1, f); 0179 if (byteswap) 0180 bswap_stardata(&data); 0181 if (mag != -500 && ((data.mag - mag) > 20 && mag < 1250) || data.mag < mag) 0182 { // TODO: Make sensible magnitude limit (1250) user specifiable 0183 // TODO: Enable byteswapping 0184 fprintf(stderr, "\n\tEncountered jump of %f at star #%d in trixel %d from %f to %f.", 0185 (data.mag - mag) / 100.0, i, trixel, mag / 100.0, data.mag / 100.0); 0186 ++nerr_trixel; 0187 } 0188 mag = data.mag; 0189 if (mag > realFaintMag) 0190 { 0191 realFaintMag = mag; 0192 } 0193 if (mag > 1500) 0194 fprintf(stderr, "Magnitude > 15.00 ( = %f ) in trixel %d\n", mag / 100.0, trixel); 0195 } 0196 if (nerr_trixel > 0) 0197 fprintf(stderr, "\n * Encountered %d magnitude jumps in trixel %d\n", nerr_trixel, trixel); 0198 else 0199 fprintf(stdout, "Successful\n"); 0200 nerr += nerr_trixel; 0201 } 0202 if (MSpT != realMSpT) 0203 { 0204 fprintf(stderr, "ERROR: MSpT according to file = %d, but turned out to be %d\n", MSpT, realMSpT); 0205 nerr++; 0206 } 0207 if (realFaintMag != faintMag) 0208 { 0209 fprintf(stderr, "ERROR: Faint Magnitude according to file = %f, but turned out to be %f\n", faintMag / 100.0, 0210 realFaintMag / 100.0); 0211 nerr++; 0212 } 0213 if (nerr > 0) 0214 { 0215 fprintf(stderr, "ERROR: Exiting with %d errors\n", nerr); 0216 return 0; 0217 } 0218 fprintf(stdout, "Data validation success!\n"); 0219 return 1; 0220 } 0221 0222 void readStarList(FILE *f, u_int32_t trixel, FILE *names) 0223 { 0224 long offset; 0225 long n; 0226 int i; 0227 u_int32_t nrecs; 0228 u_int32_t trix; 0229 char bayerName[8]; 0230 char longName[32]; 0231 starData data; 0232 0233 printf("Reading star list for trixel %d\n", trixel); 0234 rewind(f); 0235 offset = index_offset + 0236 trixel * INDEX_ENTRY_SIZE; // CAUTION: Change if the size of each entry in the index table changes 0237 fseek(f, offset, SEEK_SET); 0238 fread(&trix, 4, 1, f); 0239 if (byteswap) 0240 trix = bswap_32(trix); 0241 if (trix != trixel) 0242 { 0243 fprintf( 0244 stderr, 0245 "ERROR: Something fishy in the index. I guessed that %d would be here, but instead I find %d. Aborting.\n", 0246 trixel, trix); 0247 return; 0248 } 0249 fread(&offset, 4, 1, f); 0250 if (byteswap) 0251 offset = bswap_32(offset); 0252 fread(&nrecs, 4, 1, f); 0253 if (byteswap) 0254 nrecs = bswap_32(nrecs); 0255 0256 if (fseek(f, offset, SEEK_SET)) 0257 { 0258 fprintf(stderr, 0259 "ERROR: Could not seek to position %X in the file. The file is either truncated or the indexes are " 0260 "bogus.\n", 0261 offset); 0262 return; 0263 } 0264 printf("Data for trixel %d starts at offset 0x%X and has %d records\n", trixel, offset, nrecs); 0265 0266 for (i = 0; i < nrecs; ++i) 0267 { 0268 offset = ftell(f); 0269 n = (offset - data_offset) / sizeof(starData); 0270 fread(&data, sizeof(starData), 1, f); 0271 if (byteswap) 0272 bswap_stardata(&data); 0273 printf("Entry #%d\n", i); 0274 printf("\tRA = %f\n", data.RA / 1000000.0); 0275 printf("\tDec = %f\n", data.Dec / 100000.0); 0276 printf("\tdRA/dt = %f\n", data.dRA / 10.0); 0277 printf("\tdDec/dt = %f\n", data.dDec / 10.0); 0278 printf("\tParallax = %f\n", data.parallax / 10.0); 0279 printf("\tHD Catalog # = %lu\n", data.HD); 0280 printf("\tMagnitude = %f\n", data.mag / 100.0); 0281 printf("\tB-V Index = %f\n", data.bv_index / 100.0); 0282 printf("\tSpectral Type = %c%c\n", data.spec_type[0], data.spec_type[1]); 0283 printf("\tHas a name? %s\n", ((data.flags & 0x01) ? "Yes" : "No")); 0284 /* 0285 if(data.flags & 0x01 && names) { 0286 fseek(names, n * (32 + 8) + 0xA0, SEEK_SET); 0287 fread(bayerName, 8, 1, names); 0288 fread(longName, 32, 1, names); 0289 printf("\t\tBayer Designation = %s\n", bayerName); 0290 printf("\t\tLong Name = %s\n", longName); 0291 } 0292 */ 0293 printf("\tMultiple Star? %s\n", ((data.flags & 0x02) ? "Yes" : "No")); 0294 printf("\tVariable Star? %s\n", ((data.flags & 0x04) ? "Yes" : "No")); 0295 } 0296 } 0297 0298 /** 0299 *@short Read the KStars binary file header and display its contents 0300 *@param f Binary file to read from 0301 *@returns non-zero if successful, zero if not 0302 */ 0303 0304 int readFileHeader(FILE *f) 0305 { 0306 int i; 0307 int16_t endian_id; 0308 char ASCII_text[125]; 0309 u_int8_t version_no; 0310 0311 if (f == NULL) 0312 return 0; 0313 0314 fread(ASCII_text, 124, 1, f); 0315 ASCII_text[124] = '\0'; 0316 printf("%s", ASCII_text); 0317 0318 fread(&endian_id, 2, 1, f); 0319 if (endian_id != 0x4B53) 0320 { 0321 fprintf(stdout, "Byteswapping required\n"); 0322 byteswap = 1; 0323 } 0324 else 0325 { 0326 fprintf(stdout, "Byteswapping not required\n"); 0327 byteswap = 0; 0328 } 0329 0330 fread(&version_no, 1, 1, f); 0331 fprintf(stdout, "File version number: %d\n", version_no); 0332 fread(&nfields, 2, 1, f); 0333 if (byteswap) 0334 nfields = bswap_16(nfields); 0335 fprintf(stdout, "%d fields reported\n", nfields); 0336 0337 for (i = 0; i < nfields; ++i) 0338 { 0339 fread(&(de[i]), sizeof(struct dataElement), 1, f); 0340 if (byteswap) 0341 de->scale = bswap_32(de->scale); 0342 displayDataElementDescription(&(de[i])); 0343 } 0344 0345 fread(&ntrixels, 4, 1, f); 0346 if (byteswap) 0347 ntrixels = bswap_32(ntrixels); 0348 fprintf(stdout, "Number of trixels reported = %d\n", ntrixels); 0349 0350 return 1; 0351 } 0352 0353 int main(int argc, char *argv[]) 0354 { 0355 FILE *f, *names; 0356 int16_t maglim = -500; 0357 names = NULL; 0358 if (argc <= 1) 0359 { 0360 fprintf(stderr, "USAGE: %s filename [trixel]\n", argv[0]); 0361 fprintf(stderr, "Designed for use only with KStars star data files\n"); 0362 return 1; 0363 } 0364 0365 f = fopen(argv[1], "rb"); 0366 0367 if (f == NULL) 0368 { 0369 fprintf(stderr, "ERROR: Could not open file %s for binary read.\n", argv[1]); 0370 return 1; 0371 } 0372 0373 readFileHeader(f); 0374 0375 verifyIndexValidity(f); 0376 verifyStarData(f); 0377 0378 // fread(&maglim, 2, 1, f); 0379 // fprintf(stdout, "Limiting Magnitude of Catalog File: %f\n", maglim / 100.0); 0380 0381 if (argc > 2) 0382 { 0383 /* 0384 if(argc > 3) 0385 names = fopen(argv[3], "rb"); 0386 else 0387 names = NULL; 0388 0389 fprintf(stderr, "Names = %s\n", ((names)?"Yes":"No")); 0390 */ 0391 rewind(f); 0392 readStarList(f, atoi(argv[2]), names); 0393 } 0394 0395 fclose(f); 0396 if (names) 0397 fclose(names); 0398 0399 return 0; 0400 }