File indexing completed on 2024-04-28 03:42:52

0001 /*
0002     SPDX-FileCopyrightText: 2008 Akarsh Simha <akarshsimha@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 // Use the nomadmysql2bin-split program / the shell script to create binary
0008 // dumps of star data by trixel. Thereafter use this program to merge the
0009 // pieces together and create a well-defined binary file in the binary file
0010 // format described in ../README.binfileformat
0011 
0012 #define VERBOSE          1
0013 #define HTM_LEVEL        6
0014 #define NTRIXELS         32768 // TODO: Change if HTM Level Changes
0015 #define INDEX_ENTRY_SIZE 12
0016 
0017 #include "binfile.h"
0018 
0019 #include <mysql/mysql.h>
0020 #include <sys/types.h>
0021 #include <stdlib.h>
0022 #include <stdio.h>
0023 #include <math.h>
0024 #include <string.h>
0025 
0026 /*
0027  * struct to store star data, to be written in this format, into the binary file.
0028  */
0029 
0030 typedef struct deepStarData
0031 {
0032     int32_t RA;
0033     int32_t Dec;
0034     int16_t dRA;
0035     int16_t dDec;
0036     int16_t B;
0037     int16_t V;
0038 } deepStarData;
0039 
0040 /*
0041  * Dump the data file header.
0042  *
0043  * WARNING: Must edit every time the definition of the deepStarData structures changes
0044  *
0045  * f : Data file handle
0046  */
0047 
0048 int writeDataFileHeader(FILE *f)
0049 {
0050     char ASCII_text[124];
0051     u_int16_t nfields;
0052     u_int32_t nindexes;
0053     int16_t endian_id   = 0x4B53;
0054     u_int8_t version_no = 1;
0055 
0056     if (f == NULL)
0057         return 0;
0058 
0059     nfields = 6;
0060 
0061     str2charv(ASCII_text, "KStars Star Data v1.0. To be read using the 16-bit deepStarData structure only.", 124);
0062     fwrite(ASCII_text, 124, 1, f);
0063     fwrite(&endian_id, 2, 1, f);
0064     fwrite(&version_no, 1, 1, f);
0065     fwrite(&nfields, sizeof(u_int16_t), 1, f);
0066 
0067     writeDataElementDescription(f, "RA", 4, DT_INT32, 1000000);
0068     writeDataElementDescription(f, "Dec", 4, DT_INT32, 100000);
0069     writeDataElementDescription(f, "dRA", 2, DT_INT16, 10);
0070     writeDataElementDescription(f, "dDec", 2, DT_INT16, 10);
0071     writeDataElementDescription(f, "B", 2, DT_INT16, 100);
0072     writeDataElementDescription(f, "V", 2, DT_INT16, 100);
0073 
0074     nindexes = NTRIXELS;
0075     fwrite(&nindexes, sizeof(u_int32_t), 1, f);
0076 
0077     return 1;
0078 }
0079 
0080 int main(int argc, char *argv[])
0081 {
0082     /* === Declarations === */
0083 
0084     int ret, i, exitflag;
0085     long int lim;
0086 
0087     double Mag;
0088 
0089     unsigned long us_header_offset;
0090     unsigned long usf_trix_begin;
0091     unsigned long usf_trix_count;
0092     unsigned long ntrixels;
0093     int16_t maglim;
0094     u_int8_t htm_level;
0095     u_int16_t MSpT_unnamed;
0096 
0097     char query[512];
0098     u_int32_t current_trixel;
0099 
0100     /* File streams */
0101     FILE *f;       /* Pointer to "current" file */
0102     FILE *usf;     /* Handle to star data file */
0103     FILE *usfhead; /* Handle to star header file */
0104 
0105     /* deepStarData structure */
0106     deepStarData data;
0107 
0108     /* MySQL structures */
0109     MYSQL link;
0110     MYSQL_RES *result;
0111     MYSQL_ROW row;
0112 
0113     /* Check the number of arguments */
0114     if (argc <= 6)
0115     {
0116         fprintf(stderr, "USAGE %s DataFile HeaderFile InputDataFilePrefix\n", argv[0]);
0117         fprintf(stderr, "The database used is a MySQL DB on localhost. The default table name is `nomad`\n");
0118     }
0119 
0120     /* == Open all file streams required == */
0121     /* Unnamed Star Handling */
0122     usf = fopen(argv[1], "wb");
0123     if (usf == NULL)
0124     {
0125         fprintf(stderr, "ERROR: Could not open %s [Data File] for binary write.\n", argv[1]);
0126         return 1;
0127     }
0128 
0129     usfhead = fopen(argv[2], "wb");
0130     if (usfhead == NULL)
0131     {
0132         fprintf(stderr, "ERROR: Could not open %s [Header File] for binary write.\n", argv[2]);
0133         fcloseall();
0134         return 1;
0135     }
0136 
0137     if (VERBOSE)
0138         fprintf(stdout, "Size of deepStarData structure: %d\n", sizeof(deepStarData));
0139 
0140     /* Write file headers */
0141     writeDataFileHeader(usfhead);
0142     us_header_offset = ftell(usfhead);
0143 
0144     /* Leave space in the data file for certain catalog information */
0145     /* Leave space for / write a deep magnitude limit specification in the data files */
0146     maglim = (int)(-5.0 * 100);
0147     fwrite(&maglim, 2, 1, usf); // Bogus entry
0148 
0149     /* Write a HTM level specification in the data file */
0150     htm_level = HTM_LEVEL;
0151     fwrite(&htm_level, 1, 1, usf);
0152 
0153     /* Leave space for a specification of MSpT (Maximum Stars per Trixel) in the data files */
0154     MSpT_unnamed = 0;
0155     fwrite(&MSpT_unnamed, 2, 1, usf); // Bogus entry
0156 
0157     /* Initialize some variables */
0158     usf_trix_begin =
0159         2 + 1 +
0160         2; // The 2 + 1 + 2 is to leave space for deep magnitude limit, HTM Level and MSpT specification. TODO: Change this if things change.
0161     ntrixels = 0;
0162 
0163     for (current_trixel = 0; current_trixel < NTRIXELS; ++current_trixel)
0164     {
0165         char fname[256];
0166         sprintf(fname, "%s%d", argv[3], current_trixel);
0167         FILE *trixdump;
0168         trixdump = fopen(fname, "rb");
0169         if (trixdump == NULL)
0170         {
0171             fprintf(stderr, "ERROR: Could not open %s for binary read! Exiting with INCOMPLETE data files.\n", fname);
0172             fcloseall();
0173             return 1;
0174         }
0175         usf_trix_count = 0;
0176         while (!feof(trixdump))
0177         {
0178             if (!fread(&data, sizeof(deepStarData), 1, trixdump))
0179             {
0180                 if (VERBOSE)
0181                     fprintf(stdout, "Finished transferring trixel %d (%d records)\n", current_trixel, usf_trix_count);
0182                 break;
0183             }
0184             usf_trix_count++;
0185 
0186             int16_t B = data.B;
0187             int16_t V = data.V;
0188 
0189             if (V == 30000)
0190             {
0191                 if (B - 1600 > maglim && B != 30000)
0192                 {
0193                     maglim = B - 1600;
0194                 }
0195             }
0196             else
0197             {
0198                 if (V > maglim)
0199                 {
0200                     maglim = V;
0201                 }
0202             }
0203             fwrite(&data, sizeof(deepStarData), 1, usf);
0204         }
0205 
0206         fclose(trixdump);
0207 
0208         /* Write index entries if we've changed trixel */
0209         if (VERBOSE)
0210         {
0211             fprintf(stderr, "Done with trixel %d!\n", current_trixel);
0212         }
0213         writeIndexEntry(usfhead, current_trixel, us_header_offset + NTRIXELS * INDEX_ENTRY_SIZE + usf_trix_begin,
0214                         usf_trix_count);
0215         usf_trix_begin += usf_trix_count * sizeof(deepStarData);
0216         if (usf_trix_count > MSpT_unnamed)
0217             MSpT_unnamed = usf_trix_count;
0218         ntrixels++;
0219         usf_trix_count = 0;
0220     }
0221 
0222     if (ntrixels != NTRIXELS)
0223     {
0224         fprintf(stderr,
0225                 "ERROR: Expected %u trixels, but found %u instead. Please redefine NTRIXELS in this program, or check "
0226                 "the source database for bogus trixels\n",
0227                 NTRIXELS, ntrixels);
0228     }
0229 
0230     rewind(usf);
0231     fwrite(&maglim, 2, 1, usf);
0232     fwrite(&htm_level, 1, 1, usf);
0233     fwrite(&MSpT_unnamed, 2, 1, usf);
0234 
0235     fcloseall();
0236 
0237     return 0;
0238 }