UNPKG

astrometry.js

Version:

Extract star pixel coordinates from a FITS image using JavaScript

183 lines (154 loc) 8.21 kB
/* Usage: image2xy [options] fitsname.fits Read a FITS file, find objects, and write out X, Y, FLUX to fitsname.xy.fits . [-e <extension>]: read from a single FITS extension [-O] overwrite existing output file. [-o <output-filename>] write XYlist to given filename. [-L <Lanczos-order>] [-8] don't use optimization for byte (u8) images. [-H] downsample by a factor of 2 before running simplexy. [-d <downsample-factor>] downsample by an integer factor before running simplexy. [-D <downsample-factor>] downsample, if necessary, by this many factors of two. [-s <median-filtering scale>]: set median-filter box size (default 100 pixels) [-w <PSF width>]: set Gaussian PSF sigma (default 1 pixel) [-g <sigma>]: set image noise level [-p <sigmas>]: set significance level of peaks (default 8 sigmas) [-a <saddle-sigmas>]: set "saddle" level joining peaks (default 5 sigmas) [-P <image plane>]: pull out a single plane of a multi-color image (default: first plane) [-b]: don't do (median-based) background subtraction [-G <background>]: subtract this 'global' background value; implies -b [-m]: set maximum extended object size for deblending (default 2000 pixels) [-S <background-subtracted image>]: save background-subtracted image to this filename (FITS float image) [-B <background image>]: save background image to filename [-U <smoothed background-subtracted image>]: save smoothed background-subtracted image to filename [-M <mask image>]: save mask image to filename [-C <blob-image>]: save connected-components image to filename [-v] verbose - repeat for more and more verboseness image2xy 'file.fits[1]' - process first extension. image2xy 'file.fits[2]' - process second extension image2xy file.fits+2 - same as above */ const EM_IMAGE2XY_OPTIONS = { help: 'h', //<boolean> Print available options and usage instructions verbose: 'v', //<boolean> Print verbose messages extension: 'e', //<number> Read from a single FITS extension downsampleFactor: 'D', //<number> Downsample, if necessary, by this many factors of two medianFilteringScale: 's', //<number> Set median-filter box size (default 100 pixels) psfWidth: 'w', //<number> Set Gaussian PSF sigma (default 1 pixel) noiseLevel: 'g', //<number> Set image noise level peakSigma: 'p', //<number> Set significance level of peaks (default 8 sigmas) saddleLevel: 'a', //<number> Set saddle level joining peaks (default 5 sigmas) disableBackgroundSubtraction: 'b', //<boolean> Don't do (median-based) background subtraction backgroundLevel: 'G', //<number> Subtract this 'global' background value; implies -b outputFilename: 'o', //<filename> Write XYlist to given filename. backgroundSubtractedImageName: 'S', //<filename> save background-subtracted image to this filename (FITS float image) backgroundImageName: 'B', //<filename> save background image to filename smoothedImageName: 'U', //<filename> save smoothed background-subtracted image to filename maskImageName: 'M', //<filename> save mask image to filename blobImageName: 'C' //<filename> save connected-components image to filename } var Module = Object.assign((Module || {}), { preRun: function() { // Override the default output location so that we can return it. const stdout_list = []; Module.print = function(msg) { console.log(msg); stdout_list.push(msg); } Module.exit = function() { } Module.image2xy = function (fits_file, options) { // We need a fits file buffer to do anything useful if (!fits_file) { console.log('image2xy: No fits file buffer provided.'); } // Convert options to image2xy formatted options object if (options) { options = Object.assign({}, options); Object.keys(options).forEach(function(name) { if (EM_IMAGE2XY_OPTIONS[name]) { options[EM_IMAGE2XY_OPTIONS[name]] = options[name]; delete options[name]; } }) } // Create a workspace directory in the emscripten virtual file system and go to it FS.mkdir('/workspace'); FS.chdir('/workspace'); // Link a filename to a buffer (helper method) function add_to_memfs(name, buf) { // Buffers are not copied by emscripten, this is not actually a // write but simply creates a reference to the buffer in MEMFS. const stream = FS.open(name, 'w+'); FS.write(stream, buf, 0, buf.length, 0, true); FS.close(stream); } // Build the arguments array for the main() method var args = []; if (options) { // Create the arguments list for main() method for (var prop in options) { const val = options[prop]; if (val !== undefined) { // Handle boolean flags that don't need values if (prop.match(/[O 8 H b v]/) && val) { args.push('-' + prop); continue; } // Add the flag (followed by a value) args.push('-' + prop); // Handle inputs that are not boolean or buffers if (prop.match(/[e o L d D s w g p a P G m S B U M C]/)) { // Split the value into an array, and concat with the args args = args.concat(val.toString().split(/\s/)); } } } } // Add the FITS file to the args list if (fits_file) { add_to_memfs('fits_buf.fits', fits_file); args.push('fits_buf.fits'); } // Clear the stdout_list (in case this function was called again) //stdout_list.length = 0; run(args); // Remove the source image from the workspace if (fits_file) { FS.unlink('fits_buf.fits'); } // Get the output files and remove the workspace from the virtual file system var num_files = 0; const output_files = {}; const workspace = FS.readdir('/workspace'); for (var index in workspace) { const name = workspace[index]; if (name !== '.' && name !== '..') { output_files[name] = FS.readFile(name, { encoding: 'binary' }); FS.unlink(name); num_files++; } } // Clean up the virtual file system in case of re-entry FS.chdir('/'); FS.rmdir('/workspace'); if (num_files === 1) { return Object.values(output_files).pop(); } if (num_files > 1) { return output_files; } return stdout_list.join('\n'); } // Wrapper for invoking main() method function run(args) { args = args || []; ensureInitRuntime(); var argc = args.length + 1; var argv = [allocate(intArrayFromString(Module['thisProgram']), 'i8', ALLOC_NORMAL),0,0,0]; for (var i = 0; i < argc - 1; i = i + 1) { argv = argv.concat([allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL), 0,0,0]); } argv.push(0); argv = allocate(argv, 'i32', ALLOC_NORMAL); return Module['_main'](argc, argv, 0); } } });