2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2008 Liam Girdwood
19 #define _GNU_SOURCE /* for strtof and NAN */
29 #include <libastrodb/db.h>
30 #include <libastrodb/astro.h>
31 #include <libastrodb/table.h>
32 #include <libastrodb/adbstdio.h>
34 #define FILE_NAME_SIZE 256
35 #define FLOAT_SIZE '6' /* CDS F size and below for a float else double */
36 #define IMPORT_LINE_SIZE 1024
39 * libastrodb interface version
41 #define ADB_IDX_VERSION 2
43 /*! \fn static int insert_posn_mag (void* d, void* object)
44 * \brief Insert object into dataset based upon position and mag
46 static int insert_posn_mag(void *d
, void *object
)
48 int ra
, dec
, mag
, offset
;
49 struct astrodb_table
*table
= (struct astrodb_table
*) d
;
50 struct astrodb_object_deep
*dobject
= object
;
52 if (dobject
->posn
.ra
< table
->db
->ra_min
||
53 dobject
->posn
.ra
> table
->db
->ra_max
)
55 if (dobject
->posn
.dec
< table
->db
->dec_min
||
56 dobject
->posn
.dec
> table
->db
->dec_max
)
58 if (dobject
->Vmag
> table
->db
->mag_faint
||
59 dobject
->Vmag
< table
->db
->mag_bright
)
62 ra
= floor((dobject
->posn
.ra
- table
->db
->ra_min
) /
63 table
->ra_stride_size
);
64 dec
= floor((dobject
->posn
.dec
- table
->db
->dec_min
) /
65 table
->dec_stride_size
);
66 mag
= floor((dobject
->Vmag
- table
->db
->mag_bright
) /
67 table
->mag_stride_size
);
69 offset
= table_calc_deep_offset(table
, ra
, dec
, mag
);
72 astrodb_error("failed to calculate offset for RA %3.2f"
73 " DEC %3.2f mag %3.2f\n", ra
, dec
, mag
);
77 *(table
->objects
+ offset
) =
78 astrodb_slist_prepend(*(table
->objects
+ offset
), object
);
79 (table
->status
+ offset
)->flags
= ADB_SMEM
;
80 (table
->status
+ offset
)->size
++;
84 /*! \fn static int insert_posn_type (void* d, void* object)
85 * \brief Insert object into dataset based upon position and type
87 static int insert_posn_type(void *d
, void *object
)
89 int ra
, dec
, type
, offset
;
90 struct astrodb_table
*table
= (struct astrodb_table
*) d
;
91 struct astrodb_object_deep
*dobject
= object
;
93 if (dobject
->posn
.ra
< table
->db
->ra_min
||
94 dobject
->posn
.ra
> table
->db
->ra_max
)
96 if (dobject
->posn
.dec
< table
->db
->dec_min
||
97 dobject
->posn
.dec
> table
->db
->dec_max
)
99 if (dobject
->Vmag
> table
->db
->mag_faint
||
100 dobject
->Vmag
< table
->db
->mag_bright
)
103 ra
= floor((dobject
->posn
.ra
- table
->db
->ra_min
) /
104 table
->ra_stride_size
);
105 dec
= floor((dobject
->posn
.dec
- table
->db
->dec_min
) /
106 table
->dec_stride_size
);
107 type
= dobject
->aobject
.oclass
;
109 offset
= table_calc_deep_offset(table
, ra
, dec
, type
);
111 astrodb_error("failed to calculate offset for RA %3.2f"
112 " DEC %3.2f type %3.2f\n", ra
, dec
, type
);
116 *(table
->objects
+ offset
) =
117 astrodb_slist_prepend(*(table
->objects
+ offset
), object
);
118 (table
->status
+ offset
)->flags
= ADB_SMEM
;
119 (table
->status
+ offset
)->size
++;
123 /*! \fn static int insert_hash_id (void* d, void* object)
124 * \brief Insert object into dataset based upon position and mag
126 static int insert_hash_id(void *d
, void *object
)
128 struct astrodb_table
*table
= (struct astrodb_table
*) d
;
129 int offset
= table_calc_hash(((struct astrodb_object
*) object
)->id
,
130 OBJECT_ID_SIZE
, table
->no_tiles
);
132 *(table
->objects
+ offset
) =
133 astrodb_slist_prepend(*(table
->objects
+ offset
), object
);
134 (table
->status
+ offset
)->flags
= ADB_SMEM
;
135 (table
->status
+ offset
)->size
++;
139 /*! \fn static inline int insert_hash_id_hobject(astrodb_table *table, void *object, int hid)
140 * \brief Insert object into dataset based upon position and mag
142 static inline int insert_hash_id_hobject(struct astrodb_table
*table
,
143 void *object
, int hid
)
147 offset
= table_calc_hash((char *) object
+ table
->hmaps
[hid
].offset
,
148 OBJECT_ID_SIZE
, table
->no_tiles
);
150 *(table
->hmaps
[hid
].hobjects
+ offset
) =
151 astrodb_slist_prepend(*(table
->hmaps
[hid
].hobjects
+ offset
), object
);
155 /*! \fn static int insert_posn_mag_hash (void* d, void* object)
156 * \brief Insert object into dataset based upon position and mag
158 static int insert_posn_mag_hash(void *d
, void *object
)
160 int ra
, dec
, mag
, offset
;
161 struct astrodb_table
*table
= (struct astrodb_table
*) d
;
162 struct astrodb_object_deep
*dobject
= object
;
165 if (dobject
->posn
.ra
< table
->db
->ra_min
||
166 dobject
->posn
.ra
> table
->db
->ra_max
)
168 if (dobject
->posn
.dec
< table
->db
->dec_min
||
169 dobject
->posn
.dec
> table
->db
->dec_max
)
171 if (dobject
->Vmag
> table
->db
->mag_faint
||
172 dobject
->Vmag
< table
->db
->mag_bright
)
175 ra
= floor((dobject
->posn
.ra
- table
->db
->ra_min
) /
176 table
->ra_stride_size
);
177 dec
= floor((dobject
->posn
.dec
- table
->db
->dec_min
) /
178 table
->dec_stride_size
);
179 mag
= floor((dobject
->Vmag
- table
->db
->mag_bright
) /
180 table
->mag_stride_size
);
182 offset
= table_calc_deep_offset(table
, ra
, dec
, mag
);
184 astrodb_error("failed to calculate deep offset for RA %3.2f"
185 " DEC %3.2f mag %3.2f\n", ra
, dec
, mag
);
189 *(table
->objects
+ offset
) =
190 astrodb_slist_prepend(*(table
->objects
+ offset
), object
);
191 (table
->status
+ offset
)->flags
= ADB_SMEM
;
192 (table
->status
+ offset
)->size
++;
194 for (i
= 0; i
< table
->num_hmaps
; i
++)
195 insert_hash_id_hobject(table
, object
, i
);
200 /*! \fn static int insert_posn_type_hash (void* d, void* object)
201 * \brief Insert object into dataset based upon position and type
203 static int insert_posn_type_hash(void *d
, void *object
)
205 int ra
, dec
, type
, offset
, i
;
206 struct astrodb_table
*table
= (struct astrodb_table
*) d
;
207 struct astrodb_object_deep
*dobject
= object
;
209 if (dobject
->posn
.ra
< table
->db
->ra_min
||
210 dobject
->posn
.ra
> table
->db
->ra_max
)
212 if (dobject
->posn
.dec
< table
->db
->dec_min
||
213 dobject
->posn
.dec
> table
->db
->dec_max
)
215 if (dobject
->Vmag
> table
->db
->mag_faint
||
216 dobject
->Vmag
< table
->db
->mag_bright
)
219 ra
= floor((dobject
->posn
.ra
- table
->db
->ra_min
) /
220 table
->ra_stride_size
);
221 dec
= floor((dobject
->posn
.dec
- table
->db
->dec_min
) /
222 table
->dec_stride_size
);
223 type
= dobject
->aobject
.oclass
;
224 offset
= table_calc_deep_offset(table
, ra
, dec
, type
);
226 astrodb_error("failed to calculate deep offset for RA %3.2f"
227 " DEC %3.2f type %3.2f\n", ra
, dec
, type
);
231 *(table
->objects
+ offset
) =
232 astrodb_slist_prepend(*(table
->objects
+ offset
), object
);
233 (table
->status
+ offset
)->flags
= ADB_SMEM
;
234 (table
->status
+ offset
)->size
++;
236 for (i
= 0; i
< table
->num_hmaps
; i
++)
237 insert_hash_id_hobject(table
, object
, i
);
248 * Table containing dataset insertion funcs and ID's
250 struct _insert table_insert
[] = {
251 {insert_posn_mag
, INSERT_POSN_MAG
},
252 {insert_posn_type
, INSERT_POSN_TYPE
},
253 {insert_hash_id
, INSERT_HASH_ID
},
254 {insert_posn_mag_hash
, INSERT_POSN_MAG_HASH
},
255 {insert_posn_type_hash
, INSERT_POSN_TYPE_HASH
},
258 void table_set_insert(struct astrodb_table
*table
, int id
)
262 for (i
= 0; i
< astrodb_size(table_insert
); i
++) {
263 if (id
== table_insert
[i
].id
) {
264 table
->object_insert
= table_insert
[i
].func
;
268 table
->object_insert
= NULL
;
271 /* table type insert's */
272 static int int_insert(void *dest
, void *src
)
276 *(int *) dest
= strtol(src
, &ptr
, 10);
281 static int float_insert(void *dest
, void *src
)
285 *(float *) dest
= strtof(src
, &ptr
);
287 *(float*) dest
= FP_NAN
;
292 static int double_insert(void *dest
, void *src
)
296 *(double *) dest
= strtod(src
, &ptr
);
298 *(double*) dest
= FP_NAN
;
303 static int str_insert(void *dest
, void *src
)
309 static int double_dms_mins(void *dest
, void *src
)
313 *(double *) dest
+= strtod(src
, &ptr
) / 60.0;
318 static int double_dms_secs(void *dest
, void *src
)
322 *(double *) dest
+= strtod(src
, &ptr
) / 3600.0;
327 static int sign_insert(void *dest
, void *src
)
329 if (*(char*)src
== '-')
330 *(double *) dest
*= -1.0;
333 static int double_hms_hrs(void *dest
, void *src
)
337 *(double *) dest
= strtod(src
, &ptr
) * 15.0;
342 static int double_hms_mins(void *dest
, void *src
)
346 *(double *) dest
+= strtod(src
, &ptr
) * 15.0 / 60.0;
351 static int double_hms_secs(void *dest
, void *src
)
355 *(double *) dest
+= strtod(src
, &ptr
) * 15.0 / 3600.0;
361 static int float_alt_insert(void *dest
, void *src
, void *src2
)
365 *(float *) dest
= strtof(src
, &ptr
);
367 /* is primary source invalid then try alternate source */
369 *(float *) dest
= strtof(src2
, &ptr
);
371 *(float*) dest
= FP_NAN
;
378 static int double_alt_insert(void *dest
, void *src
, void *src2
)
382 *(double *) dest
= strtod(src
, &ptr
);
384 /* is primary source invalid then try alternate source */
386 *(double *) dest
= strtod(src2
, &ptr
);
388 *(double *) dest
= FP_NAN
;
395 /*! \fn astrodb_ctype table_get_ctype(char *type)
396 * \brief Get C type from ASCII type
398 astrodb_ctype
table_get_ctype(char *type
)
405 if (*(type
+ 1) > FLOAT_SIZE
)
413 /*! \fn int table_get_csize(char *type)
414 * \brief Get C size from ASCII size
416 int table_get_csize(char *type
)
421 return strtol(type
+ 1, NULL
, 10);
423 if (*(type
+ 1) > FLOAT_SIZE
)
424 return sizeof(double);
426 return sizeof(float);
431 /*! \fn void *table_get_custom_insert(char *type)
432 * Get dataset type insert
434 void *table_get_custom_insert(char *type
)
437 return (void *) int_insert
;
439 return (void *) str_insert
;
441 if (*(type
+ 1) > FLOAT_SIZE
)
442 return (void *) double_insert
;
444 return (void *) float_insert
;
449 /*! \fn void *table_get_key_insert(astrodb_ctype type)
450 * Get dataset type insert
452 void *table_get_key_insert(astrodb_ctype type
)
455 case CT_DOUBLE_DMS_DEGS
:
457 return double_insert
;
464 case CT_DOUBLE_DMS_MINS
:
465 return double_dms_mins
;
466 case CT_DOUBLE_DMS_SECS
:
467 return double_dms_secs
;
473 case CT_DOUBLE_HMS_HRS
:
474 return double_hms_hrs
;
475 case CT_DOUBLE_HMS_MINS
:
476 return double_hms_mins
;
477 case CT_DOUBLE_HMS_SECS
:
478 return double_hms_secs
;
480 astrodb_error("Invalid column insert %d\n", type
);
484 /*! \fn void *table_get_alt_key_insert(astrodb_ctype type)
485 * Get dataset type insert
487 void *table_get_alt_key_insert(astrodb_ctype type
)
491 return double_alt_insert
;
493 return float_alt_insert
;
496 case CT_DOUBLE_DMS_DEGS
:
497 case CT_DOUBLE_DMS_MINS
:
498 case CT_DOUBLE_DMS_SECS
:
502 case CT_DOUBLE_HMS_HRS
:
503 case CT_DOUBLE_HMS_MINS
:
504 case CT_DOUBLE_HMS_SECS
:
505 astrodb_error("Invalid alt column insert %d\n", type
);
511 /*! \fn void table_get_object_insert(astrodb_table * table)
512 * \brief Get object insert func for table
513 * \todo index on position ans type/class
515 void table_get_object_insert(struct astrodb_table
*table
)
517 if (table_is_field(table
, "RA") &&
518 table_is_field(table
, "DEC") &&
519 table_is_field(table
, "Vmag")) {
521 if (table
->num_hmaps
) {
522 astrodb_info("Table Sectioned on Position, Magnitude and"
524 table_set_insert(table
, INSERT_POSN_MAG_HASH
);
526 astrodb_info("Table Sectioned on Position, Magnitude\n");
527 table_set_insert(table
, INSERT_POSN_MAG
);
532 if (table_is_field(table
, "RAh") &&
533 table_is_field(table
, "DEd") &&
534 table_is_field(table
, "Vmag")) {
536 if (table
->num_hmaps
) {
537 astrodb_info("Table Sectioned on Position, Magnitude and"
539 table_set_insert(table
, INSERT_POSN_MAG_HASH
);
541 astrodb_info("Table Sectioned on Position, Magnitude\n");
542 table_set_insert(table
, INSERT_POSN_MAG
);
547 astrodb_info("Indexing on ID\n");
548 table_set_insert(table
, INSERT_HASH_ID
);
551 static void get_import_buffer_size(struct astrodb_table
*table
)
555 table
->buffer_size
= 0;
557 for (i
= 0; i
< table
->object_fields
; i
++) {
558 if (table
->idx
[i
].l_size
> table
->buffer_size
)
559 table
->buffer_size
= table
->idx
[i
].l_size
;
563 static int import_data(struct astrodb_table
*table
, FILE *f
)
565 int i
, j
, count
= 0, short_records
= 0, insert
, warn
;
567 char buf
[IMPORT_LINE_SIZE
];
572 line
= malloc(IMPORT_LINE_SIZE
);
576 astrodb_info("Starting import with object size %d bytes\n",
579 size
= table
->record_size
+ 10;
580 for (j
= 0; j
< table
->table_size
; j
++) {
582 object
= malloc(table
->object_size
);
583 if (object
== NULL
) {
587 bzero(object
, table
->object_size
);
588 bzero(line
, IMPORT_LINE_SIZE
);
590 /* try and read a little extra padding */
591 rsize
= getline(&line
, &size
, f
);
593 if (rsize
< table
->record_size
)
596 /* create row by inserting column (field) data */
597 for (i
= 0; i
< table
->object_fields
; i
++) {
598 bzero(buf
, table
->buffer_size
);
599 strncpy(buf
, line
+ table
->idx
[i
].l_offset
,
600 table
->idx
[i
].l_size
);
601 insert
= table
->idx
[i
].
602 insert(object
+ table
->idx
[i
].s_offset
, buf
);
604 astrodb_warn(" blank field %s\n",
605 table
->idx
[i
].symbol
);
611 astrodb_warn("At line %d :-\n", count
);
612 astrodb_warn("line %s\n\n", line
);
615 /* insert row into table */
616 count
+= table
->object_insert(table
, object
);
618 astrodb_info("Got %d short records\n", short_records
);
619 astrodb_info("Imported %d records\n", count
);
624 static int import_data_alt(struct astrodb_table
*table
, FILE *f
)
626 int i
, j
, k
, count
= 0, short_records
= 0, warn
, insert
;
628 char buf
[IMPORT_LINE_SIZE
], buf2
[IMPORT_LINE_SIZE
];
633 line
= malloc(IMPORT_LINE_SIZE
);
637 astrodb_info("Starting import with object size %d bytes\n",
639 astrodb_info("Importing %d alt fields\n", table
->alt_fields
);
641 size
= table
->record_size
+ 10;
642 for (j
= 0; j
< table
->table_size
; j
++) {
643 object
= calloc(1, table
->object_size
);
644 if (object
== NULL
) {
649 bzero(object
, table
->object_size
);
650 bzero(line
, IMPORT_LINE_SIZE
);
652 /* try and read a little extra padding */
653 rsize
= getline(&line
, &size
, f
);
655 if (rsize
< table
->record_size
)
658 /* create row by inserting colunm (field) data */
659 for (i
= 0; i
< table
->object_fields
; i
++) {
660 bzero(buf
, table
->buffer_size
);
661 strncpy(buf
, line
+ table
->idx
[i
].l_offset
,
662 table
->idx
[i
].l_size
);
663 insert
= table
->idx
[i
].insert(
664 object
+ table
->idx
[i
].s_offset
, buf
);
666 astrodb_warn(" blank field %s\n",
667 table
->idx
[i
].symbol
);
672 /* complete row by inserting alt column (field) data */
673 for (k
= 0; k
< table
->alt_fields
; k
++) {
674 bzero(buf
, table
->buffer_size
);
675 bzero(buf2
, table
->buffer_size
);
676 strncpy(buf
, line
+ table
->alt_idx
[k
].pri
.l_offset
,
677 table
->alt_idx
[k
].pri
.l_size
);
678 strncpy(buf2
, line
+ table
->alt_idx
[k
].sec
.l_offset
,
679 table
->alt_idx
[k
].sec
.l_size
);
680 insert
= table
->alt_idx
[k
].insert(object
+
681 table
->alt_idx
[k
].pri
.s_offset
,
684 astrodb_warn(" blank fields %s %s\n",
685 table
->alt_idx
[k
].pri
.symbol
,
686 table
->alt_idx
[k
].sec
.symbol
);
692 astrodb_warn("At line %d :-\n", count
);
693 astrodb_warn("line %s\n\n", line
);
696 /* insert row into table */
697 count
+= table
->object_insert(table
, object
);
699 astrodb_info("Got %d short records\n", short_records
);
700 astrodb_info("Imported %d records\n", count
);
705 /*! \fn int table_import(astrodb_table * table, char *file, astrodb_progress progress)
706 * \brief Import an ASCII dataset into table tile array
708 int table_import(struct astrodb_table
*table
, char *file
)
712 if (!table
->object_insert
) {
713 astrodb_error("Invalid object insert\n");
717 f
= fopen(file
, "r");
719 astrodb_error("failed to open file %s\n", file
);
723 table_order_index(table
);
725 get_import_buffer_size(table
);
727 if (table
->alt_fields
)
728 import_data_alt(table
, f
);
730 import_data(table
, f
);