void read_or_make_image(const char* filename, double value, size_t width, size_t height, cl_float** image) { // if file is given if(filename) { // file width and height size_t w, h; // read FITS file read_fits(filename, TFLOAT, &w, &h, (void**)image); // make sure dimensions agree if(w != width || h != height) errorf(filename, 0, "wrong dimensions: %zu x %zu (should be %zu x %zu)", w, h, width, height); } else { // total size of image size_t size = width*height; // make array for image cl_float* x = malloc(size*sizeof(cl_float)); if(!x) errori(NULL); // set value for each pixel for(size_t i = 0; i < size; ++i) x[i] = value; // output image *image = x; } }
int read_regions_mask(const char* maskfile, const char* imagefile, const pcsdata* pcs, size_t width, size_t height, int** mask) { // FITS header of image int status = 0; fitsfile* fptr; char* fitshdr; int nkeys; // regions specifications char* regspec; Regions reg; RegionsMask regmask; int nmask; // read image FITS header to string fits_open_file(&fptr, imagefile, READONLY, &status); fits_convert_hdr2str(fptr, 0, NULL, 0, &fitshdr, &nkeys, &status); fits_close_file(fptr, &status); if(status) fits_error(imagefile, status); // make regions specification regspec = malloc(strlen(maskfile) + 3); if(!regspec) errori(NULL); sprintf(regspec, "@%s\n", maskfile); // load regions from file reg = OpenRegions(fitshdr, regspec, NULL); if(!reg) { // could not read regions free(regspec); free(fitshdr); return 1; } // allocate zero-filled space for mask *mask = calloc(width*height, sizeof(int)); if(!*mask) error(NULL, 0); // filter regions for image section nmask = FilterRegions(reg, pcs->rx, pcs->rx + width - 1, pcs->ry, pcs->ry + height - 1, 1, ®mask, NULL); // go through regions and mask pixels for(int i = 0; i < nmask; ++i) for(int x = regmask[i].xstart; x <= regmask[i].xstop; ++x) (*mask)[(regmask[i].y - 1)*width + (x - 1)] = 1; // clean up CloseRegions(reg); free(regspec); free(fitshdr); // mask created return 0; }
void make_weight(const cl_float* image, const cl_float* gain, double offset, size_t width, size_t height, cl_float** weight) { // total size of weights size_t size = width*height; // make array for weights cl_float* w = malloc(size*sizeof(cl_float)); if(!w) errori(NULL); // calculate inverse variance for each pixel for(size_t i = 0; i < size; ++i) w[i] = gain[i]/(image[i] + offset); // output weights *weight = w; }
extern int refine_first(void) /* initial refinement pass */ { int *esamp = (int *)zprev; /* OK to reuse */ int hl_erri = errori(HL_ERR); int nextra = 0; int x, y, xp, yp; int neigh; register int n, np; if (sizeof(int) < sizeof(*zprev)) error(CONSISTENCY, "code error in refine_first"); if (!silent) { printf("\tFirst refinement pass..."); fflush(stdout); } memset((void *)esamp, '\0', sizeof(int)*hres*vres); /* * In our initial pass, we look for lower error pixels from * the same objects in the previous frame, and copy them here. */ for (y = vres; y--; ) for (x = hres; x--; ) { n = fndx(x, y); if (obuffer[n] == OVOID) continue; if (xmbuffer[n] == MO_UNK) continue; xp = x + xmbuffer[n]; if ((xp < 0) | (xp >= hres)) continue; yp = y + ymbuffer[n]; if ((yp < 0) | (yp >= vres)) continue; np = fndx(xp, yp); /* make sure we hit same object */ if (oprev[np] != obuffer[n]) continue; /* is previous frame error lower? */ if (aprev[np] < AMIN + ATIDIFF) continue; if (aprev[np] <= abuffer[n] + ATIDIFF) continue; /* shadow & highlight detection */ if (abuffer[n] > hl_erri && getclosest(&neigh, 1, x, y) && bigdiff(cbuffer[neigh], cprev[np], HL_ERR*(.9+.2*frandom()))) continue; abuffer[n] = aprev[np] - ATIDIFF; copycolor(cbuffer[n], cprev[np]); esamp[n] = 1; /* record extrapolated sample */ nextra++; } for (n = hres*vres; n--; ) /* update sample counts */ if (esamp[n]) sbuffer[n] = 1; if (!silent) printf("extrapolated %d pixels\n", nextra); return(1); }
void read_fits(const char* filename, int datatype, size_t* width, size_t* height, void** image) { int status = 0; // the FITS file fitsfile* fptr; // metadata int bitpix; int naxis; long naxes[2]; // total number of pixels long npix; // reading offset long fpixel[2] = { 1, 1 }; // size of output image pixels size_t spix = 0; // open FITS file fits_open_image(&fptr, filename, READONLY, &status); if(status) fits_error(filename, status); // get metadata fits_get_img_param(fptr, 2, &bitpix, &naxis, naxes, &status); if(status) fits_error(filename, status); // check dimension of image if(naxis != 2) errorf(filename, 0, "file has %d axes (should be 2)", naxis); // set dimensions *width = naxes[0]; *height = naxes[1]; // size of output pixels switch(datatype) { case TINT: spix = sizeof(int); break; case TFLOAT: spix = sizeof(float); break; case TDOUBLE: spix = sizeof(double); break; default: error("read_fits(): datatype %d not implemented", datatype); } // create array for pixels npix = naxes[0]*naxes[1]; *image = malloc(npix*spix); if(!*image) errori(NULL); // read pixels into array fits_read_pix(fptr, datatype, fpixel, npix, NULL, *image, NULL, &status); if(status) fits_error(filename, status); // close file again fits_close_file(fptr, &status); if(status) fits_error(filename, status); }
void find_mode(size_t nvalues, const cl_float values[], const cl_float mask[], double* mode, double* fwhm) { double min, max, dx; size_t* counts; long i, j; // make sure there are values if(nvalues == 0) { *mode = MODE_NAN; *fwhm = 0; return; } // find minimum and maximum of values min = max = values[0]; for(i = 1; i < nvalues; ++i) { if(mask && !mask[i]) continue; if(values[i] < min) min = values[i]; else if(values[i] > max) max = values[i]; } // if the values are amodal, return if(min == max) { *mode = min; *fwhm = 0; return; } // bin width dx = (max - min)/MODE_BINS; // create array for bin counts counts = calloc(MODE_BINS, sizeof(size_t)); if(!counts) errori(NULL); // count frequency in each bin for(i = 0; i < nvalues; ++i) { if(mask && !mask[i]) continue; j = (values[i] - min)/dx; if(j == MODE_BINS) j -= 1; counts[j] += 1; } // find bin with most counts j = 0; for(i = 1; i < MODE_BINS; ++i) if(counts[i] > counts[j]) j = i; // mode is at middle of most common bin *mode = min + (j + 0.5)*dx; // find right half maximum for(i = j+1; i < MODE_BINS; ++i) if(counts[i] < 0.5*counts[j]) break; // right half maximum *fwhm = i*dx; // find left half maximum for(i = j; i > 0; --i) if(counts[i-1] < 0.5*counts[j]) break; // full width at half maximum *fwhm -= (i-1)*dx; // done with counts free(counts); }