-
Notifications
You must be signed in to change notification settings - Fork 2
/
js-wrapper.js
183 lines (154 loc) · 8.02 KB
/
js-wrapper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
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);
}
}
});