Search code examples
cbinaryfilesastronomy

Can't read real numbers from Yale Bright Star Catalog


I'm currently trying to read some star data from the BSC. I've managed to read in the header and that shows up more or less correct, but I'm having trouble reading in the star data itself. The specification states that values are stored as 4/8-byte "Real" numbers, which I assumed meant floats/doubles, but the Ascension and Declination I get are all wrong, a good bit above the trillions for one and zero for the other. The magnitude is also wrong, despite it just being an integer, which I could read fine in the header. Here's and image of the output thus far. Any know what I'm doing wrong?


Solution

  • Alright, after some more testing, I managed to solve my problem. The crucial step was to abandon the binary file altogether and use the ASCII file instead. I had some problems reading from it before due to how it was formatted, but I came up with a method that worked:

    /* Struct to store all the attributes I'm interested in */
    struct StarData_t{
        char Name[11];
        char SpType[21];
        float GLON, GLAT, Vmag;
    };
    
    int main()
    {
        /* Allocate a list of the structs
        (the BSC has 9110 entries) */
        struct StarData_t stars[9110];
        /* Open the catalog */
        FILE *fptr = fopen("catalog", "r");
        if(fptr != NULL){
            /* Create a buffer for storing the star entries.
            The ASCII file has one entry per line.
            Each line has a max length of 197,
            which becomes 199 with the newline and null terminator,
            so I round up to 200. */
            size_t star_size = 200;
            char *star_buffer;
            star_buffer = (char *)malloc(star_size * sizeof(char));
            /* Create a buffer for reading in the numbers.
            The catalog has no numbers longer than 6 characters,
            So I allocate 7 to account for the newline. */
            char data_buffer[7];
            /* For each entry in the BSC... */
            for(int i = 0; i < 9110; i++){
                /* Read the line to the buffer */
                getline(&star_buffer, &star_size, fptr);
                /* And put the data in the matching index,
                Using the data buffer to create the floats */
                // GLON
                strncpy(data_buffer, &(star_buffer[90]), 6);
                data_buffer[6] = '\0';
                stars[i].GLON = fmod(atof(data_buffer)+180, 360)-180;
                // GLAT
                strncpy(data_buffer, &(star_buffer[96]), 6);
                data_buffer[6] = '\0';
                stars[i].GLAT = atof(data_buffer);
                // Vmag
                strncpy(data_buffer, &(star_buffer[102]), 5);
                data_buffer[5] = '\0';
                stars[i].Vmag = atof(data_buffer);
                // Name
                strncpy(stars[i].Name, &(star_buffer[4]), 10);
                stars[i].Name[10] = '\0';
                // Spectral Type
                strncpy(stars[i].SpType, &(star_buffer[127]), 20);
                stars[i].SpType[20] = '\0';
    
                printf("Name: %s, Long: %7.2f, Lat: %6.2f, Vmag: %4.2f, SpType: %s\n", stars[i].Name, stars[i].GLON, stars[i].GLAT, stars[i].Vmag, stars[i].SpType);
            }
            free(star_buffer);
        }
    }
    

    Hope this is useful!