/* Gliese-3 stardata generator, $Revision$ * Written by Brad Jones 960322 * Based on the 2.0 stardata generator by Winchell Chung * This program is released under the GNU General Program License. * It may be redistributed and modified freely, but attributions must be made. * * Command line options: (NOTE: X, Y, and Z are numbers; FILE is a filename) * '-n' turns on non-interactive mode * '-ref X Y Z' sets the reference point to (X, Y, Z) * Default is (0, 0, 0) * '-mindist X' changes minimum distance to X; default is 0 * '-maxdist X' changes maximum distance to X; default is 5 * '-minlum X' changes minimum luminosity to X; default is 0 * '-maxlum X' changes maximum luminosity to X; default is 200 * '-nobin' turns off binaries; default is binaries on * '-long' turns on long output; default is short * '-xlong' turns on extra-long output; default is short * '-o FILE' sets the output filename to FILE; default is 'gliese3.out' * * Revision history: * Revision 1.0: created by Brad Jones * Mac version: Winchell Chung * */ #include #include #include /* Added by Winchell Chung */ #include #include #include typedef int boolean; #define TRUE 1 #define FALSE 0 #define DEG_TO_RAD 0.0174532925 /* This structure holds the data for one record of the Gliese-3 catalog. Each field is commented with the name of its field in the catalog data and its datatype in [square brackets]. Lengths of character arrays have had 1 added to them to allow room for the terminating '\0'. */ typedef struct stardata { char identifier[9]; /* Identifier of the star [A8]. */ char components[3]; /* Component of multi-star system [A2] */ char distrel; /* Reliability of the distance [A1] */ int ra_hours; /* Right ascension, hours component [I2] */ int ra_minutes; /* Right ascension, minutes component [I2] */ int ra_seconds; /* Right ascension, seconds component [I2] */ int dec_degrees; /* Declination, degrees incl. sign [A1 + I2] */ double dec_minutes; /* Declination, minutes component [F4.1] */ double propermotion; /* Total proper motion [F6.3] */ boolean pm_uncertain; /* TRUE if proper motion uncertain [A1] */ double pm_direction; /* Direction angle of proper motion [F5.1] */ double radialvelocity; /* Radial velocity [F6.1] */ char rv_remark[4]; /* Remarks on radial velocity [A3] */ char spectraltype[13]; /* Spectral type or color class [A12] */ char spectraltype_source; /* Selected source for spectral type [A1] */ double magnitude; /* Apparent magnitude [F6.2] */ char magnitude_origin; /* Origin of magnitude [A1] */ boolean joint_magnitude; /* TRUE if joint magnitude [A1] */ double b_v_magnitude; /* B-V color magnitude [F5.2] */ char b_v_origin; /* B-V magnitude origin [A1] */ boolean joint_b_v; /* TRUE if joint B-V magnitude [A1] */ double u_b_magnitude; /* U-B color magnitude [F5.2] */ char u_b_origin; /* U-B magnitude origin [A1] */ boolean joint_u_b; /* TRUE if joint U-B magnitude [A1] */ double r_i_magnitude; /* R-I color magnitude [F5.2] */ char r_i_origin; /* R-I magnitude origin [A1] */ boolean joint_r_i; /* TRUE if joint R-I magnitude [A1] */ double trig_parallax; /* Trigonometric parallax [F6.1] */ double trig_parallax_error; /* Error in trig. parallax [F5.1] */ double parallax; /* Resulting parallax [F6.1] */ double parallax_error; /* Parallax error [F5.1] */ char parallax_code; /* Code for parallax origin [A1] */ double absolute_magnitude; /* Absolute visual magnitude [F5.2] */ char abs_mag_notes[3]; /* Notes on visual magnitude [A2] */ char abs_mag_quality; /* Qualify of absolute magnitude [A1] */ int velocity_u; /* U component of velocity [I4] */ int velocity_v; /* V component of velocity [I4] */ int velocity_w; /* W component of velocity [I4] */ long hd_designation; /* HD Designation [I6] */ char dm_designation[13]; /* DM designation [A12] */ char giclas_number[10]; /* Giclas number [A9] */ char lhs_number[6]; /* LHS number [A5] */ char other_designation[6]; /* Other designations [A5] */ char remarks[70]; /* Additional information [A69] */ /* Data below here is calculated by the program, not read from the file */ double distance; /* Distance from Sol, equals 1/parallax */ double ra; /* Right ascension in decimal degrees */ double declination; /* Declination in decimal degrees */ double x; /* X position in earth-centric coords */ double y; /* Y position in earth-centric coords */ double z; /* Z position in earth-centric coords */ double xg; /* X position in galactic coords */ double yg; /* Y position in galactic coords */ double zg; /* Z position in galactic coords */ double ref_distance; /* Distance from reference point Xr, Yr, Zr */ double luminosity; /* Luminosity relative to Sol */ } stardata; /* This structure holds the current constraints about what to print */ typedef struct constraints { double ref_x; /* X position of reference point */ double ref_y; /* Y position of reference point */ double ref_z; /* Z position of reference point */ double mindist; /* Minimum distance from reference point */ double maxdist; /* Maximum distance from reference point */ double minlum; /* Minimum luminosity */ double maxlum; /* Maximum luminosity */ boolean allowbinaries; /* Allow binaries */ int outputstyle; /* SHORT, LONG, or XLONG */ char outputfilename[256]; /* Name of output file */ FILE *outputfile; /* Output file handle */ boolean interactive; /* Ask the user for information? */ } constraints; #define OUTPUTSTYLE_SHORT 0 #define OUTPUTSTYLE_LONG 1 #define OUTPUTSTYLE_XLONG 2 /* This function takes two strings and the array offsets in the source string to copy. NOTE WELL: The offsets are _NOT_ C offsets; they are the offsets as given in GLIESE3.DOC. All newline and linefeed characters are turned into spaces. */ void string_copy(char *deststr, char *srcstr, int start, int end) { char *substring = srcstr + start - 1; char *temp; strncpy(deststr, substring, (end - start + 1)); deststr[end - start + 1] = '\0'; /* Remove 'carriage return/newline' from strings */ temp = strchr(deststr, '\n'); if (temp) *temp = ' '; temp = strchr(deststr, '\r'); if (temp) *temp = ' '; } /* Take a section of the source string and get an int out of it. Same caveats as for string_copy. */ int string_to_int(char *srcstr, int start, int end) { int outval; char formatstring[4]; char *tempstring = (char *)malloc(end - start + 2); string_copy(tempstring, srcstr, start, end); sprintf(formatstring, "%%%dd", (end - start + 1)); if (sscanf(tempstring, formatstring, &outval) != 1) return 0; else return outval; } /* Take a section of the source string and get a double out of it. Same caveats as for string_copy. */ double string_to_double(char *srcstr, int start, int end) { double outval; char formatstring[5]; char *tempstring = (char *)malloc(end - start + 2); string_copy(tempstring, srcstr, start, end); sprintf(formatstring, "%%%dlf", (end - start + 1)); if (sscanf(tempstring, formatstring, &outval) != 1) return 0.0; else return outval; } /* Take a section of the source string and get a long out of it. Same caveats as for string_copy. */ long string_to_long(char *srcstr, int start, int end) { long outval; char formatstring[5]; char *tempstring = (char *)malloc(end - start + 2); string_copy(tempstring, srcstr, start, end); sprintf(formatstring, "%%%dld", (end - start + 1)); if (sscanf(tempstring, formatstring, &outval) != 1) return 0; else return outval; } /* Do the math on the raw data to find the calculated data, like distance and luminosity */ void calculate_data(stardata *star, constraints *settings) { double rvect, phi, theta, rho; double delta_x, delta_y, delta_z; if (star->parallax != 0.0) star->distance = 1.0 / star->parallax; else star->distance = 0.0; star->ra = (star->ra_hours * 15) + (star->ra_minutes * 0.25) + (star->ra_seconds * 0.0041666666); star->declination = fabs(star->dec_degrees) + (star->dec_minutes / 60.0); if (star->dec_degrees < 0.0) star->declination = -star->declination; phi = star->ra * DEG_TO_RAD; theta = star->declination * DEG_TO_RAD; rho = star->distance; rvect = rho * cos(theta); star->x = rvect * cos(phi); star->y = rvect * sin(phi); star->z = rho * sin(theta); star->xg = -(0.0672 * star->x) - (0.8727 * star->y) - (0.4835 * star->z); star->yg = (0.4927 * star->x) - (0.4504 * star->y) + (0.7445 * star->z); star->zg = -(0.8676 * star->x) - (0.1884 * star->y) + (0.4602 * star->z); delta_x = star->x - settings->ref_x; delta_y = star->y - settings->ref_y; delta_z = star->z - settings->ref_z; star->ref_distance = sqrt((delta_x * delta_x) + (delta_y * delta_y) + (delta_z * delta_z)); star->luminosity = pow(10, (0.4 * (4.9 - star->absolute_magnitude))); } /* Convert a text string into a stardata object */ void convert_record(char *instring, stardata *star, constraints *settings) { string_copy(star->identifier, instring, 1, 8); string_copy(star->components, instring, 9, 10); star->distrel = instring[10]; star->ra_hours = string_to_int(instring, 13, 14); star->ra_minutes = string_to_int(instring, 16, 17); star->ra_seconds = string_to_int(instring, 19, 20); star->dec_degrees = string_to_int(instring, 22, 24); star->dec_minutes = string_to_double(instring, 26, 29); star->propermotion = string_to_double(instring, 31, 36); star->pm_uncertain = (instring[36] != ' '); star->pm_direction = string_to_double(instring, 38, 42); star->radialvelocity = string_to_double(instring, 44, 49); string_copy(star->rv_remark, instring, 51, 53); string_copy(star->spectraltype, instring, 55, 66); star->spectraltype_source = instring[66]; star->magnitude = string_to_double(instring, 68, 73); star->magnitude_origin = instring[73]; star->joint_magnitude = (instring[74] != ' '); star->b_v_magnitude = string_to_double(instring, 76, 80); star->b_v_origin = instring[80]; star->joint_b_v = (instring[81] != ' '); star->u_b_magnitude = string_to_double(instring, 83, 87); star->u_b_origin = instring[87]; star->joint_u_b = (instring[88] != ' '); star->r_i_magnitude = string_to_double(instring, 90, 94); star->r_i_origin = instring[94]; star->joint_r_i = (instring[95] != ' '); star->trig_parallax = string_to_double(instring, 97, 102) / 1000; star->trig_parallax_error = string_to_double(instring, 103, 107) / 1000; star->parallax = string_to_double(instring, 109, 114) / 1000; star->parallax_error = string_to_double(instring, 115, 119) / 1000; star->parallax_code = instring[119]; star->absolute_magnitude = string_to_double(instring, 122, 126); string_copy(star->abs_mag_notes, instring, 127, 128); star->abs_mag_quality = instring[128]; star->velocity_u = string_to_int(instring, 132, 135); star->velocity_v = string_to_int(instring, 137, 140); star->velocity_w = string_to_int(instring, 142, 145); star->hd_designation = string_to_long(instring, 147, 152); string_copy(star->dm_designation, instring, 154, 165); string_copy(star->giclas_number, instring, 167, 175); string_copy(star->lhs_number, instring, 177, 181); string_copy(star->other_designation, instring, 183, 187); string_copy(star->remarks, instring, 189, 257); calculate_data(star, settings); } /* Check if this star should be printed; print it if it should */ void print_record(stardata *star, constraints *settings) { if ((star->ref_distance <= settings->maxdist) && (star->ref_distance >= settings->mindist) && (star->luminosity <= settings->maxlum) && (star->luminosity >= settings->minlum) && (settings->allowbinaries || (star->components[0] == ' '))) { if (settings->outputstyle == OUTPUTSTYLE_SHORT) { fprintf(settings->outputfile, "%8s%2s %12s%9.4f %9.4f %+8.3f %+8.3f %+8.3f %8.5f %s\n", star->identifier, star->components, star->spectraltype, star->distance, star->ref_distance, star->x, star->y, star->z, star->luminosity, star->remarks); } else { fprintf(settings->outputfile, "-----------------------------------------------------------\n"); fprintf(settings->outputfile, "Gliese code: %s%s", star->identifier, star->components); fprintf(settings->outputfile, "Spectral type: %s", star->spectraltype); fprintf(settings->outputfile, "Luminosity: %8.5f\n", star->luminosity); fprintf(settings->outputfile, "Remarks: %s\n", star->remarks); fprintf(settings->outputfile, "Distance: %9.4f pc", star->distance); fprintf(settings->outputfile, " (%5.4f pc from reference point)\n", star->ref_distance); fprintf(settings->outputfile, "Coordinates: Earth-based (%+5.3f, %+5.3f, %+5.3f)\n", star->x, star->y, star->z); fprintf(settings->outputfile, " Galactic (%+5.3f, %+5.3f, %+5.3f)\n", star->xg, star->yg, star->zg); if (settings->outputstyle == OUTPUTSTYLE_XLONG) { fprintf(settings->outputfile, "HD Designation: %12ld DM Number: %s\n", star->hd_designation, star->dm_designation); fprintf(settings->outputfile, "Giclas designation: %s LHS Designation: %s\nOther designation: %s\n", star->giclas_number, star->lhs_number, star->other_designation); } } } } /* Input one double-precision value. Repeat until a valid value is entered. */ double input_double(void) { char input[256]; double output; while (TRUE) { fgets(input, 256, stdin); if (sscanf(input, " %lf ", &output) != 1) { printf("Entry not understood. Please try again.\n"); } else { return output; } } } /* Input an integer. Repeat until a valid value is entered. */ int input_integer(void) { char input[256]; int output; while (TRUE) { fgets(input, 256, stdin); if (sscanf(input, " %d ", &output) != 1) { printf("Entry not understood. Please try again.\n"); } else { return output; } } } /* Set the settings to reasonable defaults */ void init_settings(constraints *settings) { settings->ref_x = 0.0; settings->ref_y = 0.0; settings->ref_z = 0.0; settings->mindist = 0.0; settings->maxdist = 5.0; settings->minlum = 0.0; settings->maxlum = 200.0; settings->allowbinaries = TRUE; settings->outputstyle = OUTPUTSTYLE_SHORT; strcpy(settings->outputfilename, "gliese3.out"); settings->interactive = TRUE; return; } /* Get the settings from the user */ void get_user_settings(constraints *settings) { boolean done = FALSE; while (!done) { printf("\nCurrent settings:\n\n"); printf("1) Reference point: (%4.3f, %4.3f, %4.3f)\n", settings->ref_x, settings->ref_y, settings->ref_z); printf("2) Minimum distance: %4.3f\n", settings->mindist); printf("3) Maximum distance: %4.3f\n", settings->maxdist); printf("4) Minimum luminosity: %4.3f\n", settings->minlum); printf("5) Maximum luminosity: %4.3f\n", settings->maxlum); printf("6) Allow multiples: %s\n", (settings->allowbinaries ? "TRUE" : "FALSE")); printf("7) Output style: %s\n", (settings->outputstyle == OUTPUTSTYLE_SHORT ? "SHORT" : (settings->outputstyle == OUTPUTSTYLE_LONG ? "LONG" : "EXTRALONG"))); printf("8) Output filename: %s\n", settings->outputfilename); printf("9) DONE\n\n"); printf("Enter selection: "); switch(input_integer()) { case 1: printf("Enter reference point X coordinate: "); settings->ref_x = input_double(); printf("Enter reference point Y coordinate: "); settings->ref_y = input_double(); printf("Enter reference point Z coordinate: "); settings->ref_z = input_double(); break; case 2: printf("Enter minimum distance: "); settings->mindist = input_double(); if (settings->maxdist < settings->mindist) settings->maxdist = settings->mindist; break; case 3: printf("Enter maximum distance: "); settings->maxdist = input_double(); if (settings->mindist > settings->maxdist) settings->mindist = settings->maxdist; break; case 4: printf("Enter minimum luminosity: "); settings->minlum = input_double(); if (settings->maxlum < settings->minlum) settings->maxlum = settings->minlum; break; case 5: printf("Enter maximum luminosity: "); settings->maxlum = input_double(); if (settings->minlum > settings->maxlum) settings->minlum = settings->maxlum; break; case 6: settings->allowbinaries = !settings->allowbinaries; break; case 7: settings->outputstyle++; if (settings->outputstyle > OUTPUTSTYLE_XLONG) settings->outputstyle = OUTPUTSTYLE_SHORT; break; case 8: printf("Enter new filename: "); fgets(settings->outputfilename, 256, stdin); /* Remove the trailing return */ settings->outputfilename[strlen(settings->outputfilename) - 1] = '\0'; break; case 9: done = TRUE; break; default: printf("Input not understood.\n"); break; } } } /* Print the header for the output file */ void print_header(constraints *settings) { settings->outputfile = fopen(settings->outputfilename, "w"); if (settings->outputfile == (FILE *)NULL) { printf("Unable to open file; printing to standard output.\n"); settings->outputfile = stdout; } fprintf(settings->outputfile, "Output settings: Reference point (%4.3f, %4.3f, %4.3f)\n", settings->ref_x, settings->ref_y, settings->ref_z); fprintf(settings->outputfile, "Distance range %4.3f-%4.3f pc; Luminosity range %4.3f-%4.3f\n", settings->mindist, settings->maxdist, settings->minlum, settings->maxlum); fprintf(settings->outputfile, "Binaries are%s allowed.\n", (settings->allowbinaries ? "" : " not")); if (settings->outputstyle == OUTPUTSTYLE_SHORT) fprintf(settings->outputfile, "GlieseID Spectrum DistPC RefDistPC X Y Z Lum Remarks\n"); } int main() { stardata star; constraints settings; FILE *datafile; char instring[258]; short a; /* 26mar96 Winchell Chung */ init_settings(&settings); get_user_settings(&settings); print_header(&settings); a = 3805; /* 26mar96 Winchell Chung */ datafile = fopen("GLIESE3.DAT", "r"); while (fgets(instring, 258, datafile)) { convert_record(instring, &star, &settings); print_record(&star, &settings); /* 26mar96 Winchell Chung */ printf("[%d] Gliese code: %s%s %s\n", a, star.identifier, star.components, star.remarks); a--; fgets(instring, 258, datafile); /* get the trailing line feed */ } }