• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kstars

  • sources
  • kde-4.12
  • kdeedu
  • kstars
  • kstars
  • data
  • tools
nomadbinfile2mysql.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 nomadbinfile2mysql.cpp -- Convert USNO NOMAD binary file to a MySQL database
3  -------------------
4  begin : Sat Jul 2 2011
5  copyright : (C) 2011 by Akarsh Simha
6  email : akarshsimha@gmail.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 /*
19  * NOTE: I modified nomadbinfiletester.c to do this -- Akarsh
20  */
21 
22 /*
23  * TODO: VERY UGLY CODE. Please fix it some day. Preferably now. This
24  * file was created from a modified C file, and needs to be recast
25  * into the C++ way of writing stuff, i.e. with classes etc.
26  */
27 
28 #include "nomadbinfile2mysql.h"
29 #include "binfile.h"
30 #include "angconversion.h"
31 #include "MeshIterator.h"
32 #include <iostream>
33 #include <string.h>
34 #include <stdio.h>
35 
36 using namespace std;
37 
38 NOMADStarDataWriter::NOMADStarDataWriter( FILE *f, int HTMLevel, MYSQL *link, char *_db_tbl ) {
39  m_MySQLLink = link;
40  DataFile = f;
41  // Create a new shiny HTMesh
42  m_Mesh = new HTMesh( HTMLevel, HTMLevel );
43  strcpy( db_tbl, _db_tbl );
44  m_HeaderRead = false;
45 }
46 
47 NOMADStarDataWriter::~NOMADStarDataWriter() {
48  delete m_Mesh;
49 }
50 
51 void NOMADStarDataWriter::bswap_stardata( DeepStarData *stardata ) {
52  stardata->RA = bswap_32( stardata->RA );
53  stardata->Dec = bswap_32( stardata->Dec );
54  stardata->dRA = bswap_16( stardata->dRA );
55  stardata->dDec = bswap_16( stardata->dDec );
56  stardata->B = bswap_16( stardata->B );
57  stardata->V = bswap_16( stardata->V );
58 }
59 
63 bool NOMADStarDataWriter::createTable() {
64  // TODO: This is not working. Investigate.
65  char create_query[2048];
66  sprintf( create_query, "CREATE TABLE IF NOT EXISTS `%s` (`Trixel` int(32) NOT NULL COMMENT 'Trixel Number', `RA` double NOT NULL COMMENT 'RA Hours', `Dec` double NOT NULL COMMENT 'Declination Degrees', `dRA` double NOT NULL COMMENT 'Proper Motion along RA', `dDec` double NOT NULL COMMENT 'Proper Motion along Dec', `PM` double NOT NULL COMMENT 'Proper Motion (magnitude)', `V` float NOT NULL COMMENT 'Visual Magnitude', `B` float NOT NULL COMMENT 'Blue Magnitude', `Mag` float NOT NULL COMMENT 'Magnitude for sorting', `UID` int(64) NOT NULL auto_increment COMMENT 'Unique ID', `Copies` tinyint(8) NOT NULL COMMENT 'Number of Copies of the star', PRIMARY KEY (`UID`), UNIQUE KEY `UID` (`UID`), KEY `Trixel` (`Trixel`,`PM`,`Mag`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1", db_tbl );
67 
68  if ( mysql_query( m_MySQLLink, create_query ) ) {
69  cerr << "ERROR: Table creation failed!" << endl;
70  return false;
71  }
72  return true;
73 }
74 
80 void NOMADStarDataWriter::calculatePMCoords( double startRA, double startDec, double dRA, double dDec, double *endRA, double *endDec, float years ) {
81  // (Translated from Perl)
82  double theta0 = hour2rad( startRA );
83  double lat0 = deg2rad( startDec );
84 
85  double PMperyear = sqrt( dRA * dRA + dDec * dDec );
86 
87  double dir0 = ( years > 0.0 ) ? atan2( dRA, dDec ) : atan2( -dRA, -dDec ); // If years < 0, we're precessing backwards
88  double PM = PMperyear * fabs( years );
89 
90  double dst = deg2rad( arcsec2deg( PM / 1000.0 ) ); // Milliarcsecond -> radian
91 
92  double phi0 = M_PI/2.0 - lat0;
93 
94  double lat1 = asin( sin(lat0) * cos(dst) +
95  cos(lat0) * sin(dst) * cos(dir0) ); // Cosine rule on a sphere
96  double dtheta = atan2( sin(dir0) * sin(dst) * cos(lat0),
97  cos(dst) - sin(lat0)*sin(lat1) );
98 
99  *endRA = rad2hour(theta0 + dtheta);
100  *endDec = rad2deg(lat1);
101 }
102 
106 bool NOMADStarDataWriter::insertStarData( unsigned int trixel, const DeepStarData * const data ) {
107  char query[2048];
108  float mag;
109  float B, V, RA, Dec, dRA, dDec;
110 
111  // Rescale the data from the structure
112  B = ((double)data->B)/1000.0;
113  V = ((double)data->V)/1000.0;
114  RA = ((double)data->RA)/1000000.0;
115  Dec =((double)data->Dec)/100000.0;
116  dRA = ((double)data->dRA)/1000.0;
117  dDec = ((double)data->dDec)/1000.0;
118 
119  // Check if the supplied trixel is really the trixel in which the
120  // star is in according to its RA and Dec. If that's not the case,
121  // this star is a duplicate and must be ignored
122  unsigned int originalTrixelID = m_Mesh->index( RA, Dec );
123  if( trixel != originalTrixelID )
124  return true; // Ignore this star.
125 
126  // Magnitude for sorting.
127  if( V == 30.0 && B != 30.0 ) {
128  mag = B - 1.6;
129  }
130  else {
131  mag = V;
132  }
133 
134  // Compute the proper motion
135  double RA1, Dec1, RA2, Dec2;
136  double PM; // Magnitude of the proper motion in milliarcseconds per year
137 
138  PM = sqrt( dRA * dRA + dDec * dDec );
139 
140  calculatePMCoords( RA, Dec, dRA, dDec, &RA1, &Dec1, PM_MILLENIA * -1000. );
141  calculatePMCoords( RA, Dec, dRA, dDec, &RA2, &Dec2, PM_MILLENIA * 1000. );
142 
143  unsigned int TrixelList[900];
144  int ntrixels = 0;
145 
146  double separation = sqrt( hour2deg(RA1 - RA2) * hour2deg(RA1 - RA2) + (Dec1 - Dec2) * (Dec1 - Dec2) ); // Separation in degrees // ugly.
147  if( separation > 50.0 / 60.0 ) { // 50 arcminutes
148  m_Mesh->intersect( RA1, Dec1, RA2, Dec2 );
149  MeshIterator trixels( m_Mesh );
150  while( trixels.hasNext() ) {
151  TrixelList[ ntrixels ] = trixels.next();
152  ntrixels++;
153  }
154  }
155  else {
156  TrixelList[ 0 ] = originalTrixelID;
157  ntrixels = 1;
158  }
159 
160  if( ntrixels == 0 ) {
161  cerr << "Ntrixels is zero in trixel " << originalTrixelID;
162  return false;
163  }
164 
165  for( int i = 0; i < ntrixels; ++i ) {
166  sprintf( query, "INSERT INTO `%s` (`Trixel`, `RA`, `Dec`, `dRA`, `dDec`, `B`, `V`, `mag`, `PM`, `Copies`) VALUES (\'%d\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%u\')", db_tbl, TrixelList[ i ], RA, Dec, dRA, dDec, B, V, mag, PM,
167  ( (TrixelList[ i ] == originalTrixelID) ? ntrixels : 0 ) // Duplicates get a 'Copies' value of 0. The real star gets the actual value.
168  );
169  if( mysql_query( m_MySQLLink, query ) ) {
170  cerr << "MySQL INSERT INTO failed! Query was: " << endl << query << endl;
171  return false;
172  }
173  }
174  return true;
175 }
176 
177 bool NOMADStarDataWriter::truncateTable() {
178  // Truncate table. TODO: Issue warning etc
179  char query[60];
180  sprintf( query, "TRUNCATE TABLE `%s`", db_tbl );
181  if( mysql_query( m_MySQLLink, query ) ) {
182  cerr << "Truncate table query \"" << query << "\" failed!" << endl;
183  return false;
184  }
185  return true;
186 }
187 
191 bool NOMADStarDataWriter::writeStarDataToDB() {
192  int8_t HTM_Level;
193  u_int16_t MSpT;
194  u_int32_t nstars;
195  u_int32_t offset;
196  unsigned int trixel;
197  DeepStarData data;
198  int16_t mag;
199 
200  /*
201  // TODO: FIX THIS // FIXME
202  // We must at least check if the HTM level matches
203  fseek( DataFile, m_IndexOffset - 3, SEEK_SET );
204  fread( &HTM_Level, 1, 1, DataFile );
205  fprintf( stdout, "HTMesh Level: %d\n", HTM_Level );
206  if( HTM_Level != m_Mesh->level() ) {
207  cerr << "ERROR: HTMesh Level in file (" << HTM_Level << ") and HTM_LEVEL in program (" << m_Mesh->level() << ") differ." << endl
208  << "Please set the define directive for HTM_LEVEL in the header file correctly and rebuild."
209  << endl;
210  return false;
211  }
212  */
213 
214  for( trixel = 0; trixel < ntrixels; ++trixel ) {
215  fseek( DataFile, m_IndexOffset + trixel * INDEX_ENTRY_SIZE + 4 , SEEK_SET );
216  fread( &offset, 4, 1, DataFile );
217  fread( &nstars, 4, 1, DataFile );
218 
219  /* If offset > 2^31 - 1, do the fseek in two steps */
220  if( offset > (unsigned)(pow2(31) - 1) ) {
221  fseek( DataFile, pow2(31) - 1, SEEK_SET );
222  fseek( DataFile, offset - pow2(31) + 1, SEEK_CUR );
223  }
224  else
225  fseek( DataFile, offset, SEEK_SET );
226 
227  for( int i = 0; i < nstars; ++i ) {
228  fread( &data, sizeof( DeepStarData ), 1, DataFile );
229  if( byteswap ) bswap_stardata( &data );
230 
232  {
233  char query[2048];
234  float mag;
235  float B, V, RA, Dec, dRA, dDec;
236 
237  // Rescale the data from the structure
238  B = ((double)data.B)/1000.0;
239  V = ((double)data.V)/1000.0;
240  RA = ((double)data.RA)/1000000.0;
241  Dec =((double)data.Dec)/100000.0;
242  dRA = ((double)data.dRA)/1000.0;
243  dDec = ((double)data.dDec)/1000.0;
244 
245  // Check if the supplied trixel is really the trixel in which the
246  // star is in according to its RA and Dec. If that's not the case,
247  // this star is a duplicate and must be ignored
248  unsigned int originalTrixelID = m_Mesh->index( hour2deg(RA), Dec );
249  if( trixel != originalTrixelID ) {
250  cout << "Trixel = " << trixel << ", but this is the original Trixel ID: " << originalTrixelID << ". Skipping" << endl;
251  cout << "Skipped star has (RA, Dec) = " << RA << Dec << "; (dRA, dDec) = " << dRA << dDec << "; and (B, V) = " << B << V << "." << endl;
252  cout << "This suspected duplicate is star " << i << "in trixel " << trixel;
253  continue;
254  }
255 
256  // Magnitude for sorting.
257  if( V == 30.0 && B != 30.0 ) {
258  mag = B - 1.6;
259  }
260  else {
261  mag = V;
262  }
263 
264  // Compute the proper motion
265  double RA1, Dec1, RA2, Dec2, RA1deg, RA2deg;
266  double PM; // Magnitude of the proper motion in milliarcseconds per year
267 
268  PM = sqrt( dRA * dRA + dDec * dDec );
269 
270  calculatePMCoords( RA, Dec, dRA, dDec, &RA1, &Dec1, PM_MILLENIA * -1000. );
271  calculatePMCoords( RA, Dec, dRA, dDec, &RA2, &Dec2, PM_MILLENIA * 1000. );
272  RA1deg = hour2deg(RA1);
273  RA2deg = hour2deg(RA2);
274 
275  unsigned int TrixelList[60];
276  int nt = 0;
277 
278  double separationsqr = (RA1deg - RA2deg) * (RA1deg - RA2deg) + (Dec1 - Dec2) * (Dec1 - Dec2); // Separation in degrees // ugly.
279  if( separationsqr > 0.69 ) { // 50 arcminutes converted to degrees, squared and rounded below = 0.69. (This has nothing to do with sex positions.)
280  m_Mesh->intersect( RA1deg, Dec1, RA2deg, Dec2 );
281  MeshIterator trixels( m_Mesh );
282  while( trixels.hasNext() ) {
283  TrixelList[ nt ] = trixels.next();
284  nt++;
285  }
286  }
287  else {
288  TrixelList[ 0 ] = originalTrixelID;
289  nt = 1;
290  }
291 
292  if( nt == 0 ) {
293  cerr << "# of trixels is zero in trixel " << originalTrixelID;
294  return false;
295  }
296 
297  for( int i = 0; i < nt; ++i ) {
298  sprintf( query, "INSERT INTO `%s` (`Trixel`, `RA`, `Dec`, `dRA`, `dDec`, `B`, `V`, `mag`, `PM`, `Copies`) VALUES (\'%d\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%lf\', \'%u\')", db_tbl, TrixelList[ i ], RA, Dec, dRA, dDec, B, V, mag, PM,
299  ( (TrixelList[ i ] == originalTrixelID) ? nt : 0 ) // Duplicates get a 'Copies' value of 0. The real star gets the actual value.
300  );
301  if( mysql_query( m_MySQLLink, query ) ) {
302  cerr << "MySQL INSERT INTO failed! Query was: " << endl << query << endl;
303  return false;
304  }
305  }
306  }
307  }
308  if( trixel % 100 == 0 )
309  cout << "Finished trixel " << trixel << endl;
310  }
311 
312  return true;
313 }
314 
315 
316 bool NOMADStarDataWriter::readFileHeader() {
317  int i;
318  int16_t endian_id;
319  char ASCII_text[125];
320  u_int8_t version_no;
321  u_int16_t nfields;
322 
323 
324  if( !DataFile )
325  return false;
326 
327  fread(ASCII_text, 124, 1, DataFile);
328  ASCII_text[124] = '\0';
329  printf("%s", ASCII_text);
330 
331  fread(&endian_id, 2, 1, DataFile);
332  if(endian_id != 0x4B53) {
333  fprintf( stdout, "Byteswapping required\n" );
334  byteswap = 1;
335  }
336  else {
337  fprintf( stdout, "Byteswapping not required\n" );
338  byteswap = 0;
339  }
340 
341  fread(&version_no, 1, 1, DataFile);
342  fprintf( stdout, "Version number: %d\n", version_no );
343 
344  fread(&nfields, 2, 1, DataFile);
345 
346  // Just to read those many bytes
347  // TODO: Don't waste time and memory. fseek.
348  dataElement de;
349  for(i = 0; i < nfields; ++i)
350  fread(&de, sizeof(struct dataElement), 1, DataFile);
351 
352  fread(&ntrixels, 4, 1, DataFile);
353  if( byteswap ) ntrixels = bswap_32( ntrixels );
354  fprintf( stdout, "Number of trixels reported = %d\n", ntrixels );
355 
356  m_IndexOffset = ftell( DataFile );
357 
358  m_HeaderRead = true;
359 
360  return true;
361 }
362 
363 bool NOMADStarDataWriter::write() {
364  if( !readFileHeader() )
365  return false;
366  if( !createTable() )
367  return false;
368  truncateTable();
369  if( !writeStarDataToDB() )
370  return false;
371 }
372 
373 int main(int argc, char *argv[]) {
374  MYSQL link;
375  FILE *f;
376  char db_tbl[20];
377  char db_name[20];
378 
379  if(argc <= 5) {
380  fprintf(stderr, "USAGE: %s <NOMAD bin file> <MySQL DB User> <Password> <DB Name> <Table Name>\n", argv[0]);
381  return 1;
382  }
383 
384  strcpy(db_tbl, argv[5]);
385  strcpy(db_name, argv[4]);
386 
387  f = fopen(argv[1], "r");
388 
389  if(f == NULL) {
390  fprintf(stderr, "ERROR: Could not open file %s for binary read.\n", argv[1]);
391  return 1;
392  }
393 
394  /* Open the Database */
395  if(mysql_init( &link ) == NULL) {
396  fprintf(stderr, "ERROR: Failed to initialize MySQL connection!\n");
397  return 1;
398  }
399  MYSQL *ret;
400  ret = mysql_real_connect(&link, "localhost", argv[2], argv[3], db_name, 0, NULL, 0);
401 
402  if(!ret) {
403  fprintf(stderr, "ERROR: MySQL connect failed for the following reason: %s\n", mysql_error(&link));
404  fcloseall();
405  return 1;
406  }
407 
408  if(mysql_select_db(&link, db_name)) {
409  fprintf(stderr, "ERROR: Could not select MySQL database %s. MySQL said: %s", db_name, mysql_error(&link));
410  fcloseall();
411  mysql_close(&link);
412  return 1;
413  }
414 
415  NOMADStarDataWriter writer( f, HTM_LEVEL, &link, db_tbl );
416 
417  writer.write();
418 
419  fclose(f);
420  mysql_close( &link );
421  return 0;
422 }
main
int main(int argc, char *argv[])
Definition: nomadbinfile2mysql.cpp:373
HTMesh
Definition: HTMesh.h:58
rad2hour
double rad2hour(double x)
Definition: angconversion.h:32
deg2rad
double deg2rad(double x)
Definition: angconversion.h:27
NOMADStarDataWriter::~NOMADStarDataWriter
~NOMADStarDataWriter()
Destructor.
Definition: nomadbinfile2mysql.cpp:47
nomadbinfile2mysql.h
DeepStarData::V
int16_t V
Definition: nomadbinfile2mysql.h:43
DeepStarData::dDec
int16_t dDec
Definition: nomadbinfile2mysql.h:41
NaN::f
const float f
Definition: nan.h:36
pow2
#define pow2(x)
Definition: nomadbinfile2mysql.h:21
rad2deg
double rad2deg(double x)
Definition: angconversion.h:28
dataElement
A structure describing a data field in the file.
Definition: binfilehelper.h:33
bswap_32
#define bswap_32(x)
Definition: byteorder.h:52
V
#define V(m)
Definition: RangeConvex.cpp:16
DeepStarData::dRA
int16_t dRA
Definition: nomadbinfile2mysql.h:40
PM_MILLENIA
#define PM_MILLENIA
Definition: nomadbinfile2mysql.h:25
arcsec2deg
double arcsec2deg(double x)
Definition: angconversion.h:36
DeepStarData
Definition: nomadbinfile2mysql.h:37
NOMADStarDataWriter::NOMADStarDataWriter
NOMADStarDataWriter(FILE *f, int HTMLevel, MYSQL *link, char *_db_tbl)
Constructor.
Definition: nomadbinfile2mysql.cpp:38
hour2rad
double hour2rad(double x)
Definition: angconversion.h:31
hour2deg
double hour2deg(double x)
Definition: angconversion.h:29
MeshIterator.h
INDEX_ENTRY_SIZE
#define INDEX_ENTRY_SIZE
Definition: binfile.h:44
NOMADStarDataWriter
Writes NOMAD star data.
Definition: nomadbinfile2mysql.h:52
MeshIterator
Definition: MeshIterator.h:22
DeepStarData::RA
int32_t RA
Definition: nomadbinfile2mysql.h:38
HTM_LEVEL
#define HTM_LEVEL
Definition: nomadbinfile2mysql.h:22
NOMADStarDataWriter::write
bool write()
Writes the star data into the DB by calling multiple functions.
Definition: nomadbinfile2mysql.cpp:363
DeepStarData::Dec
int32_t Dec
Definition: nomadbinfile2mysql.h:39
DeepStarData::B
int16_t B
Definition: nomadbinfile2mysql.h:42
NOMADStarDataWriter::calculatePMCoords
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.
Definition: nomadbinfile2mysql.cpp:80
angconversion.h
NOMADStarDataWriter::bswap_stardata
static void bswap_stardata(DeepStarData *stardata)
Byteswaps the DeepStarData structure.
Definition: nomadbinfile2mysql.cpp:51
bswap_16
#define bswap_16(x)
Definition: byteorder.h:47
binfile.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:36:20 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

Skip menu "kstars"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal