void* plot_index_init(plot_args_t* plotargs) { plotindex_t* args = calloc(1, sizeof(plotindex_t)); args->indexes = pl_new(16); args->qidxes = pl_new(16); args->stars = TRUE; args->quads = TRUE; args->fill = FALSE; return args; }
pl* matchfile_get_matches_for_field(matchfile* mf, int field) { pl* list = pl_new(256); for (;;) { MatchObj* mo = matchfile_read_match(mf); MatchObj* copy; if (!mo) break; if (mo->fieldnum != field) { // push back the newly-read entry... matchfile_pushback_match(mf); break; } copy = malloc(sizeof(MatchObj)); memcpy(copy, mo, sizeof(MatchObj)); pl_append(list, copy); } return list; }
multiindex_t* multiindex_new(const char* skdtfn) { multiindex_t* mi = calloc(1, sizeof(multiindex_t)); logverb("Reading star KD tree from %s...\n", skdtfn); mi->fits = anqfits_open(skdtfn); if (!mi->fits) { ERROR("Failed to open multiindex file \"%s\"", skdtfn); goto bailout; } mi->inds = pl_new(16); if (multiindex_reload_starkd(mi)) { ERROR("Failed to open multiindex star kd-tree \"%s\"", skdtfn); goto bailout; } return mi; bailout: multiindex_free(mi); return NULL; }
void bl_reverse(bl* list) { // reverse each block, and reverse the order of the blocks. pl* blocks; bl_node* node; bl_node* lastnode; int i; // reverse each block blocks = pl_new(256); for (node=list->head; node; node=node->next) { for (i=0; i<(node->N/2); i++) { memswap(NODE_CHARDATA(node) + i * list->datasize, NODE_CHARDATA(node) + (node->N - 1 - i) * list->datasize, list->datasize); } pl_append(blocks, node); } // reverse the blocks lastnode = NULL; for (i=pl_size(blocks)-1; i>=0; i--) { node = pl_get(blocks, i); if (lastnode) lastnode->next = node; lastnode = node; } if (lastnode) lastnode->next = NULL; pl_free(blocks); // swap head and tail node = list->head; list->head = list->tail; list->tail = node; list->last_access = NULL; list->last_access_n = 0; }
int main(int argc, char** args) { int c; char* wcsfn = NULL; char* outfn = NULL; char* infn = NULL; sip_t sip; double scale = 1.0; anbool pngformat = TRUE; char* hdpath = NULL; anbool HD = FALSE; cairos_t thecairos; cairos_t* cairos = &thecairos; cairo_surface_t* target = NULL; cairo_t* cairot = NULL; cairo_surface_t* surfbg = NULL; cairo_t* cairobg = NULL; cairo_surface_t* surfshapes = NULL; cairo_t* cairoshapes = NULL; cairo_surface_t* surfshapesmask = NULL; cairo_t* cairoshapesmask = NULL; cairo_surface_t* surffg = NULL; cairo_t* cairo = NULL; double lw = 2.0; // circle linewidth. double cw = 2.0; double ngc_fraction = 0.02; // NGC linewidth double nw = 2.0; // leave a gap short of connecting the points. double endgap = 5.0; // circle radius. double crad = endgap; double fontsize = 14.0; double label_offset = 15.0; int W = 0, H = 0; unsigned char* img = NULL; anbool NGC = FALSE, constell = FALSE; anbool bright = FALSE; anbool common_only = FALSE; anbool print_common_only = FALSE; int Nbright = 0; double ra, dec, px, py; int i, N; anbool justlist = FALSE; anbool only_messier = FALSE; anbool grid = FALSE; double gridspacing = 0.0; double gridcolor[3] = { 0.2, 0.2, 0.2 }; int loglvl = LOG_MSG; char halign = 'L'; char valign = 'C'; sl* json = NULL; anbool whitetext = FALSE; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'V': valign = optarg[0]; break; case 'O': halign = optarg[0]; break; case 'F': ngc_fraction = atof(optarg); break; case 'h': print_help(args[0]); exit(0); case 'J': json = sl_new(4); break; case 'G': gridspacing = atof(optarg); break; case 'g': { char *tail = NULL; gridcolor[0] = strtod(optarg,&tail); if (*tail) { tail++; gridcolor[1] = strtod(tail,&tail); } if (*tail) { tail++; gridcolor[2] = strtod(tail,&tail); } } break; case 'D': HD = TRUE; break; case 'd': hdpath = optarg; break; case 'M': only_messier = TRUE; break; case 'n': nw = atof(optarg); break; case 'f': fontsize = atof(optarg); break; case 'L': justlist = TRUE; outfn = NULL; break; case 'x': whitetext = TRUE; break; case 'v': loglvl++; break; break; case 'j': print_common_only = TRUE; break; case 'c': common_only = TRUE; break; case 'b': Nbright = atoi(optarg); break; case 'B': bright = TRUE; break; case 'N': NGC = TRUE; break; case 'C': constell = TRUE; break; case 'p': pngformat = FALSE; break; case 's': scale = atof(optarg); break; case 'o': outfn = optarg; break; case 'i': infn = optarg; break; case 'w': wcsfn = optarg; break; case 'W': W = atoi(optarg); break; case 'H': H = atoi(optarg); break; } } log_init(loglvl); log_to(stderr); fits_use_error_system(); if (optind != argc) { print_help(args[0]); exit(-1); } if (!(outfn || justlist) || !wcsfn) { logerr("Need (-o or -L) and -w args.\n"); print_help(args[0]); exit(-1); } // read WCS. logverb("Trying to parse SIP/TAN header from %s...\n", wcsfn); if (!file_exists(wcsfn)) { ERROR("No such file: \"%s\"", wcsfn); exit(-1); } if (sip_read_header_file(wcsfn, &sip)) { logverb("Got SIP header.\n"); } else { ERROR("Failed to parse SIP/TAN header from %s", wcsfn); exit(-1); } if (!(NGC || constell || bright || HD || grid)) { logerr("Neither constellations, bright stars, HD nor NGC/IC overlays selected!\n"); print_help(args[0]); exit(-1); } if (gridspacing > 0.0) grid = TRUE; // adjust for scaling... lw /= scale; cw /= scale; nw /= scale; crad /= scale; endgap /= scale; fontsize /= scale; label_offset /= scale; if (!W || !H) { W = sip.wcstan.imagew; H = sip.wcstan.imageh; } if (!(infn || (W && H))) { logerr("Image width/height unspecified, and no input image given.\n"); exit(-1); } if (infn) { cairoutils_fake_ppm_init(); img = cairoutils_read_ppm(infn, &W, &H); if (!img) { ERROR("Failed to read input image %s", infn); exit(-1); } cairoutils_rgba_to_argb32(img, W, H); } else if (!justlist) { // Allocate a black image. img = calloc(4 * W * H, 1); if (!img) { SYSERROR("Failed to allocate a blank image on which to plot!"); exit(-1); } } if (HD && !hdpath) { logerr("If you specify -D (plot Henry Draper objs), you also have to give -d (path to Henry Draper catalog)\n"); exit(-1); } if (!justlist) { /* Cairo layers: -background: surfbg / cairobg --> gets drawn first, in black, masked by surfshapesmask -shapes: surfshapes / cairoshapes --> gets drawn second, masked by surfshapesmask -foreground/text: surffg / cairo --> gets drawn last. */ surffg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H); cairo = cairo_create(surffg); cairo_set_line_join(cairo, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairo, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairo, scale, scale); //cairo_select_font_face(cairo, "helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_select_font_face(cairo, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairo, fontsize); surfshapes = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H); cairoshapes = cairo_create(surfshapes); cairo_set_line_join(cairoshapes, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairoshapes, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairoshapes, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairoshapes, scale, scale); cairo_select_font_face(cairoshapes, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairoshapes, fontsize); surfshapesmask = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H); cairoshapesmask = cairo_create(surfshapesmask); cairo_set_line_join(cairoshapesmask, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairoshapesmask, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairoshapesmask, 1.0, 1.0, 1.0, 1.0); cairo_scale(cairoshapesmask, scale, scale); cairo_select_font_face(cairoshapesmask, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairoshapesmask, fontsize); cairo_paint(cairoshapesmask); cairo_stroke(cairoshapesmask); surfbg = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H); cairobg = cairo_create(surfbg); cairo_set_line_join(cairobg, CAIRO_LINE_JOIN_BEVEL); cairo_set_antialias(cairobg, CAIRO_ANTIALIAS_GRAY); cairo_set_source_rgba(cairobg, 0, 0, 0, 1); cairo_scale(cairobg, scale, scale); cairo_select_font_face(cairobg, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairobg, fontsize); cairos->bg = cairobg; cairos->fg = cairo; cairos->shapes = cairoshapes; cairos->shapesmask = cairoshapesmask; cairos->imgW = (float)W/scale; cairos->imgH = (float)H/scale; // } if (grid) { double ramin, ramax, decmin, decmax; double ra, dec; double rastep = gridspacing / 60.0; double decstep = gridspacing / 60.0; // how many line segments int N = 10; double px, py; int i; cairo_set_source_rgba(cairo, gridcolor[0], gridcolor[1], gridcolor[2], 1.0); sip_get_radec_bounds(&sip, 100, &ramin, &ramax, &decmin, &decmax); logverb("Plotting grid lines from RA=%g to %g in steps of %g; Dec=%g to %g in steps of %g\n", ramin, ramax, rastep, decmin, decmax, decstep); for (dec = decstep * floor(decmin / decstep); dec<=decmax; dec+=decstep) { logverb(" dec=%g\n", dec); for (i=0; i<=N; i++) { ra = ramin + ((double)i / (double)N) * (ramax - ramin); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; // first time, move_to; else line_to ((ra == ramin) ? cairo_move_to : cairo_line_to)(cairo, px, py); } cairo_stroke(cairo); } for (ra = rastep * floor(ramin / rastep); ra <= ramax; ra += rastep) { //for (dec=decmin; dec<=decmax; dec += (decmax - decmin)/(double)N) { logverb(" ra=%g\n", ra); for (i=0; i<=N; i++) { dec = decmin + ((double)i / (double)N) * (decmax - decmin); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; // first time, move_to; else line_to ((dec == decmin) ? cairo_move_to : cairo_line_to)(cairo, px, py); } cairo_stroke(cairo); } cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0); } } if (constell) { N = constellations_n(); logverb("Checking %i constellations.\n", N); for (c=0; c<N; c++) { const char* shortname = NULL; const char* longname; il* lines; il* uniqstars; il* inboundstars; float r,g,b; int Ninbounds; int Nunique; cairo_text_extents_t textents; double cmass[3]; uniqstars = constellations_get_unique_stars(c); inboundstars = il_new(16); Nunique = il_size(uniqstars); debug("%s: %zu unique stars.\n", shortname, il_size(uniqstars)); // Count the number of unique stars belonging to this contellation // that are within the image bounds Ninbounds = 0; for (i=0; i<il_size(uniqstars); i++) { int star; star = il_get(uniqstars, i); constellations_get_star_radec(star, &ra, &dec); debug("star %i: ra,dec (%g,%g)\n", il_get(uniqstars, i), ra, dec); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; Ninbounds++; il_append(inboundstars, star); } il_free(uniqstars); debug("%i are in-bounds.\n", Ninbounds); // Only draw this constellation if at least 2 of its stars // are within the image bounds. if (Ninbounds < 2) { il_free(inboundstars); continue; } // Set the color based on the location of the first in-bounds star. // This is a hack -- we have two different constellation // definitions with different numbering schemes! if (!justlist && (il_size(inboundstars) > 0)) { // This is helpful for videos: ensuring that the same // color is chosen for a constellation in each frame. int star = il_get(inboundstars, 0); constellations_get_star_radec(star, &ra, &dec); if (whitetext) { r = g = b = 1; } else { color_for_radec(ra, dec, &r, &g, &b); } cairo_set_source_rgba(cairoshapes, r,g,b,0.8); cairo_set_line_width(cairoshapes, cw); cairo_set_source_rgba(cairo, r,g,b,0.8); cairo_set_line_width(cairo, cw); } // Draw circles around each star. // Find center of mass (of the in-bounds stars) cmass[0] = cmass[1] = cmass[2] = 0.0; for (i=0; i<il_size(inboundstars); i++) { double xyz[3]; int star = il_get(inboundstars, i); constellations_get_star_radec(star, &ra, &dec); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; if (!justlist) { cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); } radecdeg2xyzarr(ra, dec, xyz); cmass[0] += xyz[0]; cmass[1] += xyz[1]; cmass[2] += xyz[2]; } cmass[0] /= il_size(inboundstars); cmass[1] /= il_size(inboundstars); cmass[2] /= il_size(inboundstars); xyzarr2radecdeg(cmass, &ra, &dec); il_free(inboundstars); if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py)) continue; shortname = constellations_get_shortname(c); longname = constellations_get_longname(c); assert(shortname && longname); logverb("%s at (%g, %g)\n", longname, px, py); if (Ninbounds == Nunique) { printf("The constellation %s (%s)\n", longname, shortname); } else { printf("Part of the constellation %s (%s)\n", longname, shortname); } if (justlist) continue; // If the label will be off-screen, move it back on. cairo_text_extents(cairo, shortname, &textents); if (px < 0) px = 0; if (py < textents.height) py = textents.height; if ((px + textents.width)*scale > W) px = W/scale - textents.width; if ((py+textents.height)*scale > H) py = H/scale - textents.height; logverb("%s at (%g, %g)\n", shortname, px, py); add_text(cairos, longname, px, py, halign, valign); // Draw the lines. cairo_set_line_width(cairo, lw); lines = constellations_get_lines(c); for (i=0; i<il_size(lines)/2; i++) { int star1, star2; double ra1, dec1, ra2, dec2; double px1, px2, py1, py2; double dx, dy; double dist; double gapfrac; star1 = il_get(lines, i*2+0); star2 = il_get(lines, i*2+1); constellations_get_star_radec(star1, &ra1, &dec1); constellations_get_star_radec(star2, &ra2, &dec2); if (!sip_radec2pixelxy(&sip, ra1, dec1, &px1, &py1) || !sip_radec2pixelxy(&sip, ra2, dec2, &px2, &py2)) continue; dx = px2 - px1; dy = py2 - py1; dist = hypot(dx, dy); gapfrac = endgap / dist; cairo_move_to(cairoshapes, px1 + dx*gapfrac, py1 + dy*gapfrac); cairo_line_to(cairoshapes, px1 + dx*(1.0-gapfrac), py1 + dy*(1.0-gapfrac)); cairo_stroke(cairoshapes); } il_free(lines); } logverb("done constellations.\n"); } if (bright) { double dy = 0; cairo_font_extents_t extents; pl* brightstars = pl_new(16); if (!justlist) { cairo_set_source_rgba(cairoshapes, 0.75, 0.75, 0.75, 0.8); cairo_font_extents(cairo, &extents); dy = extents.ascent * 0.5; cairo_set_line_width(cairoshapes, cw); } N = bright_stars_n(); logverb("Checking %i bright stars.\n", N); for (i=0; i<N; i++) { const brightstar_t* bs = bright_stars_get(i); if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; if (!(bs->name && strlen(bs->name))) continue; if (common_only && !(bs->common_name && strlen(bs->common_name))) continue; if (strcmp(bs->common_name, "Maia") == 0) continue; pl_append(brightstars, bs); } // keep only the Nbright brightest? if (Nbright && (pl_size(brightstars) > Nbright)) { pl_sort(brightstars, sort_by_mag); pl_remove_index_range(brightstars, Nbright, pl_size(brightstars)-Nbright); } for (i=0; i<pl_size(brightstars); i++) { char* text; const brightstar_t* bs = pl_get(brightstars, i); if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py)) continue; if (bs->common_name && strlen(bs->common_name)) if (print_common_only || common_only) text = strdup(bs->common_name); else asprintf_safe(&text, "%s (%s)", bs->common_name, bs->name); else text = strdup(bs->name); logverb("%s at (%g, %g)\n", text, px, py); if (json) { sl* names = sl_new(4); char* namearr; if (bs->common_name && strlen(bs->common_name)) sl_append(names, bs->common_name); if (bs->name) sl_append(names, bs->name); namearr = sl_join(names, "\", \""); sl_appendf(json, "{ \"type\" : \"star\", " " \"pixelx\": %g, " " \"pixely\": %g, " " \"name\" : \"%s\", " " \"names\" : [ \"%s\" ] } " , px, py, (bs->common_name && strlen(bs->common_name)) ? bs->common_name : bs->name, namearr); free(namearr); sl_free2(names); } if (bs->common_name && strlen(bs->common_name)) printf("The star %s (%s)\n", bs->common_name, bs->name); else printf("The star %s\n", bs->name); if (!justlist) { float r,g,b; // set color based on RA,Dec to match constellations above. if (whitetext) { r = g = b = 1; } else { color_for_radec(bs->ra, bs->dec, &r, &g, &b); } cairo_set_source_rgba(cairoshapes, r,g,b,0.8); cairo_set_source_rgba(cairo, r,g,b, 0.8); } if (!justlist) add_text(cairos, text, px + label_offset, py + dy, halign, valign); free(text); if (!justlist) { // plot a black circle behind the light circle... cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); } } pl_free(brightstars); } if (NGC) { double imscale; double imsize; double dy = 0; cairo_font_extents_t extents; if (!justlist) { cairo_set_source_rgb(cairoshapes, 1.0, 1.0, 1.0); cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); cairo_set_line_width(cairo, nw); cairo_font_extents(cairo, &extents); dy = extents.ascent * 0.5; } // arcsec/pixel imscale = sip_pixel_scale(&sip); // arcmin imsize = imscale * (imin(W, H) / scale) / 60.0; N = ngc_num_entries(); logverb("Checking %i NGC/IC objects.\n", N); for (i=0; i<N; i++) { ngc_entry* ngc = ngc_get_entry(i); sl* str; sl* names; double pixsize; float ara, adec; char* text; if (!ngc) break; if (ngc->size < imsize * ngc_fraction) continue; if (ngcic_accurate_get_radec(ngc->is_ngc, ngc->id, &ara, &adec) == 0) { ngc->ra = ara; ngc->dec = adec; } if (!sip_radec2pixelxy(&sip, ngc->ra, ngc->dec, &px, &py)) continue; if (px < 0 || py < 0 || px*scale > W || py*scale > H) continue; str = sl_new(4); //sl_appendf(str, "%s %i", (ngc->is_ngc ? "NGC" : "IC"), ngc->id); names = ngc_get_names(ngc, NULL); if (names) { int n; for (n=0; n<sl_size(names); n++) { if (only_messier && strncmp(sl_get(names, n), "M ", 2)) continue; sl_append(str, sl_get(names, n)); } } sl_free2(names); text = sl_implode(str, " / "); printf("%s\n", text); pixsize = ngc->size * 60.0 / imscale; if (!justlist) { // black circle behind the white one... cairo_arc(cairobg, px, py, pixsize/2.0+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_move_to(cairoshapes, px + pixsize/2.0, py); cairo_arc(cairoshapes, px, py, pixsize/2.0, 0.0, 2.0*M_PI); debug("size: %f arcsec, pixsize: %f pixels\n", ngc->size, pixsize); cairo_stroke(cairoshapes); add_text(cairos, text, px + label_offset, py + dy, halign, valign); } if (json) { char* namelist = sl_implode(str, "\", \""); sl_appendf(json, "{ \"type\" : \"ngc\", " " \"names\" : [ \"%s\" ], " " \"pixelx\" : %g, " " \"pixely\" : %g, " " \"radius\" : %g }" , namelist, px, py, pixsize/2.0); free(namelist); } free(text); sl_free2(str); } } if (HD) { double rac, decc, ra2, dec2; double arcsec; hd_catalog_t* hdcat; bl* hdlist; int i; if (!justlist) cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0); logverb("Reading HD catalog: %s\n", hdpath); hdcat = henry_draper_open(hdpath); if (!hdcat) { ERROR("Failed to open HD catalog"); exit(-1); } logverb("Got %i HD stars\n", henry_draper_n(hdcat)); sip_pixelxy2radec(&sip, W/(2.0*scale), H/(2.0*scale), &rac, &decc); sip_pixelxy2radec(&sip, 0.0, 0.0, &ra2, &dec2); arcsec = arcsec_between_radecdeg(rac, decc, ra2, dec2); // Fudge arcsec *= 1.1; hdlist = henry_draper_get(hdcat, rac, decc, arcsec); logverb("Found %zu HD stars within range (%g arcsec of RA,Dec %g,%g)\n", bl_size(hdlist), arcsec, rac, decc); for (i=0; i<bl_size(hdlist); i++) { double px, py; char* txt; hd_entry_t* hd = bl_access(hdlist, i); if (!sip_radec2pixelxy(&sip, hd->ra, hd->dec, &px, &py)) { continue; } if (px < 0 || py < 0 || px*scale > W || py*scale > H) { logverb(" HD %i at RA,Dec (%g, %g) -> pixel (%.1f, %.1f) is out of bounds\n", hd->hd, hd->ra, hd->dec, px, py); continue; } asprintf_safe(&txt, "HD %i", hd->hd); if (!justlist) { cairo_text_extents_t textents; cairo_text_extents(cairo, txt, &textents); cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI); cairo_stroke(cairobg); cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI); cairo_stroke(cairoshapes); px -= (textents.width * 0.5); py -= (crad + 4.0); add_text(cairos, txt, px, py, halign, valign); } if (json) sl_appendf(json, "{ \"type\" : \"hd\"," " \"pixelx\": %g, " " \"pixely\": %g, " " \"name\" : \"HD %i\" }" , px, py, hd->hd); printf("%s\n", txt); free(txt); } bl_free(hdlist); henry_draper_close(hdcat); } if (json) { FILE* fout = stderr; char* annstr = sl_implode(json, ",\n"); fprintf(fout, "{ \n"); fprintf(fout, " \"status\": \"solved\",\n"); fprintf(fout, " \"git-revision\": %s,\n", AN_GIT_REVISION); fprintf(fout, " \"git-date\": \"%s\",\n", AN_GIT_DATE); fprintf(fout, " \"annotations\": [\n%s\n]\n", annstr); fprintf(fout, "}\n"); free(annstr); } sl_free2(json); json = NULL; if (justlist) return 0; target = cairo_image_surface_create_for_data(img, CAIRO_FORMAT_ARGB32, W, H, W*4); cairot = cairo_create(target); cairo_set_source_rgba(cairot, 0, 0, 0, 1); // Here's where you set the background surface's properties... cairo_set_source_surface(cairot, surfbg, 0, 0); cairo_mask_surface(cairot, surfshapesmask, 0, 0); cairo_stroke(cairot); // Add on the shapes. cairo_set_source_surface(cairot, surfshapes, 0, 0); //cairo_mask_surface(cairot, surfshapes, 0, 0); cairo_mask_surface(cairot, surfshapesmask, 0, 0); cairo_stroke(cairot); // Add on the foreground. cairo_set_source_surface(cairot, surffg, 0, 0); cairo_mask_surface(cairot, surffg, 0, 0); cairo_stroke(cairot); // Convert image for output... cairoutils_argb32_to_rgba(img, W, H); if (pngformat) { if (cairoutils_write_png(outfn, img, W, H)) { ERROR("Failed to write PNG"); exit(-1); } } else { if (cairoutils_write_ppm(outfn, img, W, H)) { ERROR("Failed to write PPM"); exit(-1); } } cairo_surface_destroy(target); cairo_surface_destroy(surfshapesmask); cairo_surface_destroy(surffg); cairo_surface_destroy(surfbg); cairo_surface_destroy(surfshapes); cairo_destroy(cairo); cairo_destroy(cairot); cairo_destroy(cairobg); cairo_destroy(cairoshapes); cairo_destroy(cairoshapesmask); free(img); return 0; }
int main(int argc, char** args) { int argchar; char* progname = args[0]; int sock; struct sockaddr_in addr; int port = 6789; unsigned int opt; pl* clients; int flags; while ((argchar = getopt (argc, args, OPTIONS)) != -1) { switch (argchar) { case 'p': port = atoi(optarg); break; case 'f': solvedfnpattern = optarg; break; case 'h': default: printHelp(progname); exit(-1); } } sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { fprintf(stderr, "Error: couldn't create socket: %s\n", strerror(errno)); exit(-1); } opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) { fprintf(stderr, "Warning: failed to setsockopt() to reuse address.\n"); } flags = fcntl(sock, F_GETFL, 0); if (flags == -1) { fprintf(stderr, "Warning: failed to get socket flags: %s\n", strerror(errno)); } else { flags |= O_NONBLOCK; if (fcntl(sock, F_SETFL, flags) == -1) { fprintf(stderr, "Warning: failed to set socket flags: %s\n", strerror(errno)); } } memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); // gcc with strict-aliasing warn about this cast but according to "the internet" // it's okay because we're not dereferencing the cast pointer. if (bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in))) { fprintf(stderr, "Error: couldn't bind socket: %s\n", strerror(errno)); exit(-1); } if (listen(sock, 1000)) { fprintf(stderr, "Error: failed to listen() on socket: %s\n", strerror(errno)); exit(-1); } printf("Listening on port %i.\n", port); fflush(stdout); signal(SIGINT, sighandler); clients = pl_new(32); // wait for a connection or i/o... while (1) { struct sockaddr_in clientaddr; socklen_t addrsz = sizeof(clientaddr); FILE* fid; fd_set rset; struct timeval timeout; int res; int maxval = 0; int i; timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO(&rset); maxval = sock; for (i=0; i<pl_size(clients); i++) { int val; fid = pl_get(clients, i); val = fileno(fid); FD_SET(val, &rset); if (val > maxval) maxval = val; } assert(maxval<FD_SETSIZE); FD_SET(sock, &rset); res = select(maxval+1, &rset, NULL, NULL, &timeout); if (res == -1) { if (errno != EINTR) { fprintf(stderr, "Error: select(): %s\n", strerror(errno)); exit(-1); } } if (bailout) break; if (!res) continue; for (i=0; i<pl_size(clients); i++) { fid = pl_get(clients, i); if (FD_ISSET(fileno(fid), &rset)) { if (handle_request(fid)) { fprintf(stderr, "Error from fileno %i\n", fileno(fid)); pl_remove(clients, i); i--; continue; } } } if (FD_ISSET(sock, &rset)) { // See comment about strict aliasing above. Should be okay, despite gcc warning. int s = accept(sock, (struct sockaddr*)&clientaddr, &addrsz); if (s == -1) { fprintf(stderr, "Error: failed to accept() on socket: %s\n", strerror(errno)); continue; } if (addrsz != sizeof(clientaddr)) { fprintf(stderr, "Error: client address has size %i, not %i.\n", addrsz, (uint)sizeof(clientaddr)); continue; } printf("Connection from %s.\n", inet_ntoa(clientaddr.sin_addr)); fflush(stdout); fid = fdopen(s, "a+b"); pl_append(clients, fid); } } printf("Closing socket...\n"); if (close(sock)) { fprintf(stderr, "Error: failed to close socket: %s\n", strerror(errno)); } return 0; }
int main(int argc, char *argv[]) { int argchar; char* infn = NULL; char* outfn = NULL; FILE* fin = NULL; FILE* fout = NULL; pl* cols; char* progname = argv[0]; int nextens; int ext; int NC; int start, size; anqfits_t* anq = NULL; qfits_table* outtable; unsigned char* buffer; cols = pl_new(16); while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'c': pl_append(cols, optarg); break; case 'i': infn = optarg; break; case 'o': outfn = optarg; break; case '?': case 'h': printHelp(progname); return 0; default: return -1; } if (!infn || !outfn || !pl_size(cols)) { printHelp(progname); exit(-1); } fin = fopen(infn, "rb"); if (!fin) { ERROR("Failed to open input file %s: %s\n", infn, strerror(errno)); exit(-1); } fout = fopen(outfn, "wb"); if (!fout) { ERROR("Failed to open output file %s: %s\n", outfn, strerror(errno)); exit(-1); } // copy the main header exactly. anq = anqfits_open(infn); if (!anq) { ERROR("Failed to read \"%s\"", infn); exit(-1); } start = anqfits_header_start(anq, 0); size = anqfits_header_size (anq, 0); if (pipe_file_offset(fin, start, size, fout)) { ERROR("Failed to copy primary header.\n"); exit(-1); } NC = pl_size(cols); nextens = anqfits_n_ext(anq); printf("Translating %i extensions.\n", nextens); buffer = NULL; for (ext=1; ext<nextens; ext++) { int c2, c; int columns[NC]; int sizes[NC]; int offsets[NC]; int offset = 0; int off, n; int totalsize = 0; const int BLOCK=1000; qfits_table* table; qfits_header* header; qfits_header* tablehdr; if (ext%100 == 0) { printf("Extension %i.\n", ext); fflush(stdout); } if (!anqfits_is_table(anq, ext)) { ERROR("extention %i isn't a table.\n", ext); // HACK - just copy it. return -1; } table = anqfits_get_table(anq, ext); if (!table) { ERROR("failed to open table: file %s, extension %i.\n", infn, ext); return -1; } header = anqfits_get_header(anq, ext); if (!header) { ERROR("failed to read header: extension %i\n", ext); exit(-1); } outtable = qfits_table_new(outfn, QFITS_BINTABLE, 0, NC, table->nr); outtable->tab_w = 0; for (c=0; c<pl_size(cols); c++) { columns[c] = -1; } for (c=0; c<pl_size(cols); c++) { char* colname = pl_get(cols, c); qfits_col* col; c2 = fits_find_column(table, colname); if (c2 == -1) { ERROR("Extension %i: failed to find column named %s\n", ext, colname); exit(-1); } col = table->col + c2; columns[c] = c2; sizes[c] = col->atom_nb * col->atom_size; offsets[c] = offset; offset += sizes[c]; qfits_col_fill(outtable->col + c, col->atom_nb, col->atom_dec_nb, col->atom_size, col->atom_type, col->tlabel, col->tunit, col->nullval, col->tdisp, col->zero_present, col->zero, col->scale_present, col->scale, outtable->tab_w); outtable->tab_w += sizes[c]; } totalsize = offset; tablehdr = qfits_table_ext_header_default(outtable); // add any headers from the original table that aren't part of the BINTABLE extension. fits_copy_non_table_headers(tablehdr, header); qfits_header_dump(tablehdr, fout); qfits_header_destroy(tablehdr); buffer = realloc(buffer, totalsize * BLOCK); for (off=0; off<table->nr; off+=n) { if (off + BLOCK > table->nr) n = table->nr - off; else n = BLOCK; for (c=0; c<pl_size(cols); c++) qfits_query_column_seq_to_array_no_endian_swap (table, columns[c], off, n, buffer + offsets[c], totalsize); if (fwrite(buffer, totalsize, n, fout) != n) { ERROR("Error writing a block of data: ext %i: %s\n", ext, strerror(errno)); exit(-1); } } qfits_table_close(outtable); fits_pad_file(fout); qfits_header_destroy(header); qfits_table_close(table); } free(buffer); if (fclose(fout)) { ERROR("Error closing output file: %s\n", strerror(errno)); } fclose(fin); anqfits_close(anq); pl_free(cols); return 0; }
int main(int argc, char** args) { int c; FILE* fconst = NULL; uint32_t nstars; size_t mapsize; void* map; unsigned char* hip; FILE* fhip = NULL; int i; pl* cstars; il* alluniqstars; sl* shortnames; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case 'h': print_help(args[0]); exit(0); } } if (optind != argc) { print_help(args[0]); exit(-1); } for (i=0; i<sizeof(const_dirs)/sizeof(char*); i++) { char fn[256]; snprintf(fn, sizeof(fn), "%s/%s", const_dirs[i], constfn); fprintf(stderr, "render_constellation: Trying file: %s\n", fn); fconst = fopen(fn, "rb"); if (fconst) break; } if (!fconst) { fprintf(stderr, "render_constellation: couldn't open any constellation files.\n"); return -1; } for (i=0; i<sizeof(hip_dirs)/sizeof(char*); i++) { char fn[256]; snprintf(fn, sizeof(fn), "%s/%s", hip_dirs[i], hipparcos_fn); fprintf(stderr, "render_constellation: Trying hip file: %s\n", fn); fhip = fopen(fn, "rb"); if (fhip) break; } if (!fhip) { fprintf(stderr, "render_constellation: unhip\n"); return -1; } // first 32-bit int: if (fread(&nstars, 4, 1, fhip) != 1) { fprintf(stderr, "render_constellation: failed to read nstars.\n"); return -1; } v32_letoh(&nstars); fprintf(stderr, "render_constellation: Found %i Hipparcos stars\n", nstars); mapsize = nstars * HIP_SIZE + HIP_OFFSET; map = mmap(0, mapsize, PROT_READ, MAP_SHARED, fileno(fhip), 0); hip = ((unsigned char*)map) + HIP_OFFSET; // for each constellation, its il* of lines. cstars = pl_new(16); alluniqstars = il_new(16); shortnames = sl_new(16); for (c=0;; c++) { char shortname[16]; int nlines; int i; il* stars; if (feof(fconst)) break; if (fscanf(fconst, "%s %d ", shortname, &nlines) != 2) { fprintf(stderr, "failed to parse name+nlines (constellation %i)\n", c); fprintf(stderr, "file offset: %i (%x)\n", (int)ftello(fconst), (int)ftello(fconst)); return -1; } //fprintf(stderr, "Name: %s. Nlines %i.\n", shortname, nlines); stars = il_new(16); sl_append(shortnames, shortname); pl_append(cstars, stars); for (i=0; i<nlines; i++) { int star1, star2; if (fscanf(fconst, " %d %d", &star1, &star2) != 2) { fprintf(stderr, "failed parse star1+star2\n"); return -1; } il_insert_unique_ascending(alluniqstars, star1); il_insert_unique_ascending(alluniqstars, star2); il_append(stars, star1); il_append(stars, star2); } fscanf(fconst, "\n"); } fprintf(stderr, "render_constellations: Read %i constellations.\n", c); printf("static const int constellations_N = %i;\n", sl_size(shortnames)); /* for (c=0; c<sl_size(shortnames); c++) { printf("static const char* shortname_%i = \"%s\";\n", c, sl_get(shortnames, c)); } printf("static const char* shortnames[] = {"); for (c=0; c<sl_size(shortnames); c++) { printf("shortname_%i,", c); } printf("};\n"); */ printf("static const char* shortnames[] = {"); for (c=0; c<sl_size(shortnames); c++) { printf("\"%s\",", sl_get(shortnames, c)); } printf("};\n"); printf("static const int constellation_nlines[] = {"); for (c=0; c<pl_size(cstars); c++) { il* stars = pl_get(cstars, c); printf("%i,", il_size(stars)/2); } printf("};\n"); for (c=0; c<pl_size(cstars); c++) { il* stars = pl_get(cstars, c); printf("static const int constellation_lines_%i[] = {", c); for (i=0; i<il_size(stars); i++) { int s = il_get(stars, i); int ms = il_index_of(alluniqstars, s); printf("%s%i", (i?",":""), ms); } printf("};\n"); } printf("static const int* constellation_lines[] = {"); for (c=0; c<pl_size(cstars); c++) { printf("constellation_lines_%i,", c); } printf("};\n"); printf("static const int stars_N = %i;\n", il_size(alluniqstars)); printf("static const double star_positions[] = {"); for (i=0; i<il_size(alluniqstars); i++) { int s = il_get(alluniqstars, i); double ra, dec; hip_get_radec(hip, s, &ra, &dec); printf("%g,%g,", ra, dec); } printf("};\n"); munmap(map, mapsize); fclose(fconst); fclose(fhip); return 0; }
sl* sl_new(int blocksize) { pl* lst = pl_new(blocksize); assert(lst); return lst; }
int main(int argc, char **argv) { int argchar; startree_t* starkd; double ra=0.0, dec=0.0, radius=0.0; sl* tag = sl_new(4); anbool tagall = FALSE; char* starfn = NULL; int loglvl = LOG_MSG; char** myargs; int nmyargs; anbool getinds = FALSE; double* radec; int* inds; int N; int i; char* rdfn = NULL; pl* tagdata = pl_new(16); il* tagsizes = il_new(16); fitstable_t* tagalong = NULL; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'o': rdfn = optarg; break; case 'I': getinds = TRUE; break; case 'r': ra = atof(optarg); break; case 'd': dec = atof(optarg); break; case 'R': radius = atof(optarg); break; case 't': sl_append(tag, optarg); break; case 'T': tagall = TRUE; break; case 'v': loglvl++; break; case '?': fprintf(stderr, "Unknown option `-%c'.\n", optopt); case 'h': printHelp(argv[0]); break; default: return -1; } nmyargs = argc - optind; myargs = argv + optind; if (nmyargs != 1) { ERROR("Got %i arguments; expected 1.\n", nmyargs); printHelp(argv[0]); exit(-1); } starfn = myargs[0]; log_init(loglvl); starkd = startree_open(starfn); if (!starkd) { ERROR("Failed to open star kdtree"); exit(-1); } logmsg("Searching kdtree %s at RA,Dec = (%g,%g), radius %g deg.\n", starfn, ra, dec, radius); startree_search_for_radec(starkd, ra, dec, radius, NULL, &radec, &inds, &N); logmsg("Got %i results.\n", N); if (!N) goto done; if (tagall) { int j, M; M = startree_get_tagalong_N_columns(starkd); for (j=0; j<M; j++) sl_append(tag, startree_get_tagalong_column_name(starkd, j)); } if (sl_size(tag)) { tagalong = startree_get_tagalong(starkd); if (!tagalong) { ERROR("Failed to find tag-along table in index"); exit(-1); } } if (rdfn) { rdlist_t* rd = rdlist_open_for_writing(rdfn); il* colnums = il_new(16); if (!rd) { ERROR("Failed to open output file %s", rdfn); exit(-1); } if (rdlist_write_primary_header(rd)) { ERROR("Failed to write header to output file %s", rdfn); exit(-1); } for (i=0; i<sl_size(tag); i++) { const char* col = sl_get(tag, i); char* units; tfits_type type; int arraysize; void* data; int colnum; int itemsize; if (fitstable_find_fits_column(tagalong, col, &units, &type, &arraysize)) { ERROR("Failed to find column \"%s\" in index", col); exit(-1); } itemsize = fits_get_atom_size(type) * arraysize; data = fitstable_read_column_array_inds(tagalong, col, type, inds, N, NULL); if (!data) { ERROR("Failed to read data for column \"%s\" in index", col); exit(-1); } colnum = rdlist_add_tagalong_column(rd, type, arraysize, type, col, NULL); il_append(colnums, colnum); il_append(tagsizes, itemsize); pl_append(tagdata, data); } if (rdlist_write_header(rd)) { ERROR("Failed to write header to output file %s", rdfn); exit(-1); } for (i=0; i<N; i++) { if (rdlist_write_one_radec(rd, radec[i*2+0], radec[i*2+1])) { ERROR("Failed to write RA,Dec to output file %s", rdfn); exit(-1); } } for (i=0; i<sl_size(tag); i++) { int col = il_get(colnums, i); void* data = pl_get(tagdata, i); int itemsize = il_get(tagsizes, i); if (rdlist_write_tagalong_column(rd, col, 0, N, data, itemsize)) { ERROR("Failed to write tag-along data column %s", sl_get(tag, i)); exit(-1); } } if (rdlist_fix_header(rd) || rdlist_fix_primary_header(rd) || rdlist_close(rd)) { ERROR("Failed to close output file %s", rdfn); exit(-1); } il_free(colnums); } else { // Header printf("# RA, Dec"); if (getinds) printf(", index"); for (i=0; i<sl_size(tag); i++) printf(", %s", sl_get(tag, i)); printf("\n"); for (i=0; i<sl_size(tag); i++) { const char* col = sl_get(tag, i); char* units; tfits_type type; int arraysize; void* data; int itemsize; if (fitstable_find_fits_column(tagalong, col, &units, &type, &arraysize)) { ERROR("Failed to find column \"%s\" in index", col); exit(-1); } itemsize = fits_get_atom_size(type) * arraysize; data = fitstable_read_column_array_inds(tagalong, col, type, inds, N, NULL); if (!data) { ERROR("Failed to read data for column \"%s\" in index", col); exit(-1); } il_append(tagsizes, itemsize); pl_append(tagdata, data); } for (i=0; i<N; i++) { //int j; printf("%g, %g", radec[i*2+0], radec[i*2+1]); if (getinds) printf(", %i", inds[i]); //// FIXME -- print tag-along data of generic type. /* for (j=0; j<pl_size(tagdata); j++) { double* data = pl_get(tagdata, j); printf(", %g", data[i]); } */ printf("\n"); } } done: free(radec); free(inds); for (i=0; i<pl_size(tagdata); i++) free(pl_get(tagdata, i)); pl_free(tagdata); il_free(tagsizes); return 0; }