17#include "nomadbinfile2sqlite.h"
19#include "angconversion.h"
20#include "MeshIterator.h"
33 m_Mesh =
new HTMesh(HTMLevel, HTMLevel);
34 strcpy(db_tbl, _db_tbl);
45 stardata->RA = bswap_32(stardata->RA);
46 stardata->Dec = bswap_32(stardata->Dec);
47 stardata->dRA = bswap_16(stardata->dRA);
48 stardata->dDec = bswap_16(stardata->dDec);
49 stardata->B = bswap_16(stardata->B);
50 stardata->V = bswap_16(stardata->V);
56bool NOMADStarDataWriter::createTable()
59 char create_query[2048];
60 char index_query[2048];
63 "CREATE TABLE IF NOT EXISTS `%s` (`Trixel` int(32) NOT NULL , `RA` double NOT NULL , `Dec` double NOT NULL "
64 ", `dRA` double NOT NULL , `dDec` double NOT NULL , `PM` double NOT NULL , `V` float NOT NULL , `B` float "
65 "NOT NULL , `Mag` float NOT NULL , `UID` INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT , `Copies` int(8) NOT "
69 if (sqlite3_exec(db, create_query, 0, 0, &errorMessage) != SQLITE_OK)
72 sqlite3_free(errorMessage);
76 sprintf(index_query,
"CREATE INDEX IF NOT EXISTS `TrixelIndex` ON `%s`(`Trixel`)", db_tbl);
78 if (sqlite3_exec(db, index_query, 0, 0, &errorMessage) != SQLITE_OK)
81 sqlite3_free(errorMessage);
94 double *endDec,
float years)
97 double theta0 = hour2rad(startRA);
98 double lat0 = deg2rad(startDec);
100 double PMperyear = sqrt(dRA * dRA + dDec * dDec);
102 double dir0 = (years > 0.0) ? atan2(dRA, dDec) : atan2(-dRA, -dDec);
103 double PM = PMperyear * fabs(years);
105 double dst = deg2rad(arcsec2deg(PM / 1000.0));
107 double phi0 = M_PI / 2.0 - lat0;
109 double lat1 = asin(sin(lat0) * cos(dst) + cos(lat0) * sin(dst) * cos(dir0));
110 double dtheta = atan2(sin(dir0) * sin(dst) * cos(lat0), cos(dst) - sin(lat0) * sin(lat1));
112 *endRA = rad2hour(theta0 + dtheta);
113 *endDec = rad2deg(lat1);
119bool NOMADStarDataWriter::insertStarData(
unsigned int trixel,
const DeepStarData *
const data)
124 float B, V, RA, Dec, dRA, dDec;
127 B = ((double)data->B) / 1000.0;
128 V = ((double)data->V) / 1000.0;
129 RA = ((double)data->RA) / 1000000.0;
130 Dec = ((double)data->Dec) / 100000.0;
131 dRA = ((double)data->dRA) / 1000.0;
132 dDec = ((double)data->dDec) / 1000.0;
137 unsigned int originalTrixelID = m_Mesh->
index(RA, Dec);
138 if (trixel != originalTrixelID)
142 if (V == 30.0 && B != 30.0)
152 double RA1, Dec1, RA2, Dec2;
155 PM = sqrt(dRA * dRA + dDec * dDec);
160 unsigned int TrixelList[900];
163 double separation = sqrt(hour2deg(RA1 - RA2) * hour2deg(RA1 - RA2) +
164 (Dec1 - Dec2) * (Dec1 - Dec2));
165 if (separation > 50.0 / 60.0)
169 while (trixels.hasNext())
171 TrixelList[ntrixels] = trixels.next();
177 TrixelList[0] = originalTrixelID;
183 cerr <<
"Ntrixels is zero in trixel " << originalTrixelID;
188 "INSERT INTO `%s` (`Trixel`, `RA`, `Dec`, `dRA`, `dDec`, `B`, `V`, `mag`, `PM`, `Copies`) VALUES (:Trixel, "
189 ":RA, :Dec, :dRA, :dDec, :B, :V, :mag, :PM, :Copies)",
192 sqlite3_prepare_v2(db, query, -1, &stmt, 0);
194 if (sqlite3_exec(db,
"BEGIN TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
196 cerr <<
"SQLite INSERT INTO failed! Query was: " <<
endl <<
query <<
endl;
198 sqlite3_free(errorMessage);
202 for (
int i = 0; i < ntrixels; ++i)
204 sqlite3_bind_int(stmt, 1, TrixelList[i]);
205 sqlite3_bind_double(stmt, 2, RA);
206 sqlite3_bind_double(stmt, 3, Dec);
207 sqlite3_bind_double(stmt, 4, dRA);
208 sqlite3_bind_double(stmt, 5, dDec);
209 sqlite3_bind_double(stmt, 6, B);
210 sqlite3_bind_double(stmt, 7, V);
211 sqlite3_bind_double(stmt, 8, mag);
212 sqlite3_bind_double(stmt, 9, PM);
213 sqlite3_bind_int(stmt, 10, ((TrixelList[i] == originalTrixelID) ? ntrixels : 0));
216 sqlite3_clear_bindings(stmt);
220 if (sqlite3_exec(db,
"END TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
222 cerr <<
"SQLite INSERT INTO failed! Query was: " <<
endl <<
query <<
endl;
224 sqlite3_free(errorMessage);
228 sqlite3_finalize(stmt);
233bool NOMADStarDataWriter::truncateTable()
238 sprintf(query,
"DELETE FROM `%s`; VACUUM;", db_tbl);
239 if (sqlite3_exec(db, query, 0, 0, &errorMessage) != SQLITE_OK)
241 cerr <<
"Truncate table query \"" <<
query <<
"\" failed!" <<
endl;
243 sqlite3_free(errorMessage);
252bool NOMADStarDataWriter::writeStarDataToDB()
279 "INSERT INTO `%s` (`Trixel`, `RA`, `Dec`, `dRA`, `dDec`, `B`, `V`, `mag`, `PM`, `Copies`) VALUES (:Trixel, "
280 ":RA, :Dec, :dRA, :dDec, :B, :V, :mag, :PM, :Copies)",
283 sqlite3_prepare_v2(db, query, -1, &stmt, 0);
285 if (sqlite3_exec(db,
"BEGIN TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
287 cerr <<
"SQLite BEGIN TRANSACTION failed! Query was: " <<
endl <<
query <<
endl;
289 sqlite3_free(errorMessage);
293 for (trixel = 0; trixel < ntrixels; ++trixel)
295 fseek(DataFile, m_IndexOffset + trixel * INDEX_ENTRY_SIZE + 4, SEEK_SET);
296 fread(&offset, 4, 1, DataFile);
297 fread(&nstars, 4, 1, DataFile);
300 cerr <<
"Processing trixel " << trixel <<
" of " << ntrixels <<
endl;
303 if (offset >
unsigned(pow2(31) - 1))
305 fseek(DataFile,
unsigned(pow2(31) - 1), SEEK_SET);
306 fseek(DataFile, offset - pow2(31) + 1, SEEK_CUR);
309 fseek(DataFile, offset, SEEK_SET);
311 for (
int i = 0; i < nstars; ++i)
314 cerr <<
"Processing star " << i <<
" of " << nstars <<
" in trixel " << trixel <<
endl;
322 float B, V, RA, Dec, dRA, dDec;
325 B = ((double)data.B) / 1000.0;
326 V = ((double)data.V) / 1000.0;
327 RA = ((double)data.RA) / 1000000.0;
328 Dec = ((double)data.Dec) / 100000.0;
329 dRA = ((double)data.dRA) / 1000.0;
330 dDec = ((double)data.dDec) / 1000.0;
335 unsigned int originalTrixelID = m_Mesh->
index(hour2deg(RA), Dec);
336 if (trixel != originalTrixelID)
338 cout <<
"Trixel = " << trixel <<
", but this is the original Trixel ID: " << originalTrixelID
339 <<
". Skipping" <<
endl;
340 cout <<
"Skipped star has (RA, Dec) = " << RA << Dec <<
"; (dRA, dDec) = " << dRA << dDec
341 <<
"; and (B, V) = " << B << V <<
"." <<
endl;
342 cout <<
"This suspected duplicate is star " << i <<
"in trixel " << trixel;
347 if (V == 30.0 && B != 30.0)
357 double RA1, Dec1, RA2, Dec2, RA1deg, RA2deg;
360 PM = sqrt(dRA * dRA + dDec * dDec);
364 RA1deg = hour2deg(RA1);
365 RA2deg = hour2deg(RA2);
367 unsigned int TrixelList[60];
370 double separationsqr = (RA1deg - RA2deg) * (RA1deg - RA2deg) +
371 (Dec1 - Dec2) * (Dec1 - Dec2);
375 m_Mesh->
intersect(RA1deg, Dec1, RA2deg, Dec2);
377 while (trixels.hasNext())
379 TrixelList[nt] = trixels.next();
385 TrixelList[0] = originalTrixelID;
391 cerr <<
"# of trixels is zero in trixel " << originalTrixelID;
395 for (
int i = 0; i < nt; ++i)
397 sqlite3_bind_int(stmt, 1, TrixelList[i]);
398 sqlite3_bind_double(stmt, 2, RA);
399 sqlite3_bind_double(stmt, 3, Dec);
400 sqlite3_bind_double(stmt, 4, dRA);
401 sqlite3_bind_double(stmt, 5, dDec);
402 sqlite3_bind_double(stmt, 6, B);
403 sqlite3_bind_double(stmt, 7, V);
404 sqlite3_bind_double(stmt, 8, mag);
405 sqlite3_bind_double(stmt, 9, PM);
406 sqlite3_bind_int(stmt, 10, ((TrixelList[i] == originalTrixelID) ? ntrixels : 0));
409 sqlite3_clear_bindings(stmt);
414 if (trixel % 100 == 0 && trixel != 0)
416 if (sqlite3_exec(db,
"END TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
418 cerr <<
"SQLite END TRANSACTION failed! Query was: " <<
endl <<
query <<
endl;
420 sqlite3_free(errorMessage);
423 sqlite3_finalize(stmt);
424 sqlite3_prepare_v2(db, query, -1, &stmt, 0);
426 if (sqlite3_exec(db,
"BEGIN TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
428 cerr <<
"SQLite BEGIN TRANSACTION failed! Query was: " <<
endl <<
query <<
endl;
430 sqlite3_free(errorMessage);
434 cout <<
"Finished trixel " << trixel <<
endl;
438 if (sqlite3_exec(db,
"END TRANSACTION", 0, 0, &errorMessage) != SQLITE_OK)
440 cerr <<
"SQLite INSERT INTO failed! Query was: " <<
endl <<
query <<
endl;
442 sqlite3_free(errorMessage);
446 sqlite3_finalize(stmt);
451bool NOMADStarDataWriter::readFileHeader()
455 char ASCII_text[125];
462 fread(ASCII_text, 124, 1, DataFile);
463 ASCII_text[124] =
'\0';
464 printf(
"%s", ASCII_text);
466 fread(&endian_id, 2, 1, DataFile);
467 if (endian_id != 0x4B53)
469 fprintf(stdout,
"Byteswapping required\n");
474 fprintf(stdout,
"Byteswapping not required\n");
478 fread(&version_no, 1, 1, DataFile);
479 fprintf(stdout,
"Version number: %d\n", version_no);
481 fread(&nfields, 2, 1, DataFile);
486 for (i = 0; i < nfields; ++i)
487 fread(&de,
sizeof(
struct dataElement), 1, DataFile);
489 fread(&ntrixels, 4, 1, DataFile);
491 ntrixels = bswap_32(ntrixels);
492 fprintf(stdout,
"Number of trixels reported = %d\n", ntrixels);
494 m_IndexOffset = ftell(DataFile);
503 if (!readFileHeader())
508 if (!writeStarDataToDB())
512int main(
int argc,
char *argv[])
522 fprintf(stderr,
"USAGE: %s <NOMAD bin file> <SQLite DB File Name> <Table Name>\n", argv[0]);
526 strcpy(db_name, argv[2]);
527 strcpy(db_tbl, argv[3]);
529 f = fopen(argv[1],
"r");
533 fprintf(stderr,
"ERROR: Could not open file %s for binary read.\n", argv[1]);
538 if (sqlite3_open(db_name, &db))
540 fprintf(stderr,
"ERROR: Failed to open database: %s\n", sqlite3_errmsg(db));
HTMesh was originally intended to be a simple interface to the HTM library for the KStars project tha...
Trixel index(double ra, double dec) const
returns the index of the trixel that contains the specified point.
void intersect(double ra, double dec, double radius, BufNum bufNum=0)
NOTE: The intersect() routines below are all used to find the trixels needed to cover a geometric obj...
MeshIterator is a very lightweight class used to iterate over the result set of an HTMesh intersectio...
static void bswap_stardata(DeepStarData *stardata)
Byteswaps the DeepStarData structure.
NOMADStarDataWriter(FILE *f, int HTMLevel, MYSQL *link, char *_db_tbl)
Constructor.
bool write()
Writes the star data into the DB by calling multiple functions.
~NOMADStarDataWriter()
Destructor.
static void calculatePMCoords(double startRA, double startDec, double dRA, double dDec, double *endRA, double *endDec, float years)
Computes the (unprecessed) coordinates of a star after accounting for proper motion.
std::optional< QSqlQuery > query(const QString &queryStatement)
KCALUTILS_EXPORT QString errorMessage(const KCalendarCore::Exception &exception)
QTextStream & endl(QTextStream &stream)
A 16-byte structure that holds star data for really faint stars.
A structure describing a data field in the binary file.