138 {
140 long i_arg;
141 SCANNED_ARG *s_arg;
143 char *input = NULL, *output = NULL, *colPrefix = NULL, *background = NULL;
144 long profileType = 1, noWarnings = 0, tmpfile_used = 0, method = 0;
145 unsigned long pipeFlags = 0;
146 unsigned long backgroundFlags = 0;
147 int64_t rows, bg_rows, j;
148 long i, validColumns = 0, bg_validColumns = 0;
149 int32_t *type = NULL, *bg_type = NULL;
150 long backgroundHalfWidth = 1;
151 double backgroundLevel = 0;
152
153 int64_t rowStart = 1, rowEnd = 0;
154 long columnStart = 1, columnEnd = 0;
155
156 long *colIndex, *bg_colIndex;
157 double *colIndex2, *bg_colIndex2;
158
160 argc =
scanargs(&s_arg, argc, argv);
161
162 if (argc < 3)
164
165 for (i_arg = 1; i_arg < argc; i_arg++) {
166 if (s_arg[i_arg].arg_type == OPTION) {
167 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
168 case SET_PROFILETYPE:
169 if (s_arg[i_arg].n_items != 2)
170 SDDS_Bomb(
"invalid -profileType syntax");
171 if (strcmp("x", s_arg[i_arg].list[1]) == 0)
172 profileType = 1;
173 if (strcmp("y", s_arg[i_arg].list[1]) == 0)
174 profileType = 2;
175 break;
176 case SET_COLPREFIX:
177 if (s_arg[i_arg].n_items != 2)
178 SDDS_Bomb(
"invalid -columnPrefix syntax");
179 colPrefix = s_arg[i_arg].list[1];
180 break;
181 case SET_METHOD:
182 if (s_arg[i_arg].n_items != 2)
184 if ((strncasecmp("centralLine", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) == 0) ||
185 (strncasecmp("centerLine", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) == 0))
186 method = 1;
187 if (strncasecmp("integrated", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) == 0)
188 method = 2;
189 if (strncasecmp("averaged", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) == 0)
190 method = 3;
191 if (strncasecmp("peak", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) == 0)
192 method = 4;
193 break;
194 case SET_AREAOFINTEREST:
195 if (s_arg[i_arg].n_items != 5)
196 SDDS_Bomb(
"invalid -areaOfInterest syntax");
197 if (sscanf(s_arg[i_arg].list[1], "%" SCNd64, &rowStart) != 1 || rowStart <= 0)
198 SDDS_Bomb(
"invalid -areaOfInterest syntax or value");
199 if (sscanf(s_arg[i_arg].list[2], "%" SCNd64, &rowEnd) != 1 || rowEnd <= 0)
200 SDDS_Bomb(
"invalid -areaOfInterest syntax or value");
201 if (sscanf(s_arg[i_arg].list[3], "%ld", &columnStart) != 1 || columnStart <= 0)
202 SDDS_Bomb(
"invalid -areaOfInterest syntax or value");
203 if (sscanf(s_arg[i_arg].list[4], "%ld", &columnEnd) != 1 || columnEnd <= 0)
204 SDDS_Bomb(
"invalid -areaOfInterest syntax or value");
205 break;
206 case SET_BACKGROUND:
207 if (s_arg[i_arg].n_items < 2)
209 if (strcasecmp(s_arg[i_arg].list[1], "auto") == 0) {
210 long items;
211 items = s_arg[i_arg].n_items - 1;
212 if (!
scanItemList(&backgroundFlags, s_arg[i_arg].list + 1, &items, 0,
213 "auto", -1, NULL, 0, BACKGROUND_AUTO,
214 "halfwidth",
SDDS_LONG, &backgroundHalfWidth, 1, 0,
215 "keepNegative", -1, NULL, 0, BACKGROUND_KEEP_NEGATIVE, NULL) ||
216 !(backgroundFlags & BACKGROUND_AUTO) ||
217 backgroundHalfWidth < 0)
218 SDDS_Bomb(
"invalid -background syntax/values");
219 } else {
220 if (s_arg[i_arg].n_items != 2)
222 background = s_arg[i_arg].list[1];
223 }
224 break;
225 case SET_PIPE:
226 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
228 break;
229 default:
230 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
231 exit(EXIT_FAILURE);
232 break;
233 }
234 } else {
235 if (input == NULL)
236 input = s_arg[i_arg].list[0];
237 else if (output == NULL)
238 output = s_arg[i_arg].list[0];
239 else
241 }
242 }
243
244 if (colPrefix == NULL) {
245 fprintf(stderr, "error: missing columnPrefix\n");
246 exit(EXIT_FAILURE);
247 }
248
249 processFilenames(
"sddsimageprofiles", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
250
251
252 rows = GetData(&SDDS_orig, input, &data, &type, &colIndex, &colIndex2, colPrefix, &validColumns);
253
254 if (rows < 0) {
255 fprintf(stderr, "error: no rows in image file\n");
256 exit(EXIT_FAILURE);
257 }
258
259 if (background != NULL) {
260
261 bg_rows = GetData(&SDDS_bg, background, &bg_data, &bg_type, &bg_colIndex, &bg_colIndex2, colPrefix, &bg_validColumns);
262 if (rows != bg_rows) {
263 fprintf(stderr, "error: background has a different number of rows\n");
264 exit(EXIT_FAILURE);
265 }
266 if (validColumns != bg_validColumns) {
267 fprintf(stderr, "error: background has a different number of columns\n");
268 exit(EXIT_FAILURE);
269 }
270
271 for (i = 0; i < validColumns; i++) {
272 if (type[colIndex[i]] != bg_type[bg_colIndex[i]]) {
273 fprintf(stderr, "error: column types don't match with background image\n");
274 exit(EXIT_FAILURE);
275 }
276 if (colIndex2[i] != bg_colIndex2[i]) {
277 fprintf(stderr, "error: image rows don't match with background image\n");
278 exit(EXIT_FAILURE);
279 }
280 switch (type[colIndex[i]]) {
282 for (j = 0; j < rows; j++)
283 data[colIndex[i]].shortData[j] -= bg_data[bg_colIndex[i]].shortData[j];
284 break;
286 for (j = 0; j < rows; j++)
287 data[colIndex[i]].ushortData[j] -= bg_data[bg_colIndex[i]].ushortData[j];
288 break;
290 for (j = 0; j < rows; j++)
291 data[colIndex[i]].longData[j] -= bg_data[bg_colIndex[i]].longData[j];
292 break;
294 for (j = 0; j < rows; j++)
295 data[colIndex[i]].ulongData[j] -= bg_data[bg_colIndex[i]].ulongData[j];
296 break;
298 for (j = 0; j < rows; j++)
299 data[colIndex[i]].long64Data[j] -= bg_data[bg_colIndex[i]].long64Data[j];
300 break;
302 for (j = 0; j < rows; j++)
303 data[colIndex[i]].ulong64Data[j] -= bg_data[bg_colIndex[i]].ulong64Data[j];
304 break;
306 for (j = 0; j < rows; j++)
307 data[colIndex[i]].floatData[j] -= bg_data[bg_colIndex[i]].floatData[j];
308 break;
310 for (j = 0; j < rows; j++)
311 data[colIndex[i]].doubleData[j] -= bg_data[bg_colIndex[i]].doubleData[j];
312 break;
313 default:
314 continue;
315 }
316 }
317 }
318
319 if (backgroundFlags & BACKGROUND_AUTO) {
320 convertImageDataToDouble(data, type, rows, colIndex, validColumns);
321 backgroundLevel = estimateBackgroundLevel(data, type, rows, colIndex, validColumns, backgroundHalfWidth);
322 if (!(pipeFlags & USE_STDOUT))
323 printf("Background level subtracted: %.15g\n", backgroundLevel);
324 subtractBackgroundLevel(data, type, rows, colIndex, validColumns, backgroundLevel,
325 !(backgroundFlags & BACKGROUND_KEEP_NEGATIVE));
326 }
327
328
331 exit(EXIT_FAILURE);
332 }
333
334 if (profileType == 1) {
337 exit(EXIT_FAILURE);
338 }
341 exit(EXIT_FAILURE);
342 }
345 exit(EXIT_FAILURE);
346 }
347 } else {
350 exit(EXIT_FAILURE);
351 }
354 exit(EXIT_FAILURE);
355 }
358 exit(EXIT_FAILURE);
359 }
360 }
363 exit(EXIT_FAILURE);
364 }
365
366 if ((rowEnd > rows) || (rowEnd < rowStart))
367 rowEnd = rows;
368
369 if ((columnEnd > validColumns) || (columnEnd < columnStart))
370 columnEnd = validColumns;
371
372 if (profileType == 1) {
373 xImageProfile(data, type, rows, &SDDS_dataset, method, rowStart - 1, rowEnd, columnStart - 1, columnEnd, colIndex, colIndex2);
374 } else {
375 yImageProfile(data, type, rows, &SDDS_dataset, method, rowStart - 1, rowEnd, columnStart - 1, columnEnd, colIndex, colIndex2);
376 }
377
378
381 exit(EXIT_FAILURE);
382 }
383
384 for (i = 0; i < validColumns; i++) {
385 switch (type[colIndex[i]]) {
387 free(data[colIndex[i]].shortData);
388 break;
390 free(data[colIndex[i]].ushortData);
391 break;
393 free(data[colIndex[i]].longData);
394 break;
396 free(data[colIndex[i]].ulongData);
397 break;
399 free(data[colIndex[i]].long64Data);
400 break;
402 free(data[colIndex[i]].ulong64Data);
403 break;
405 free(data[colIndex[i]].floatData);
406 break;
408 free(data[colIndex[i]].doubleData);
409 break;
410 default:
411 continue;
412 }
413 }
414 free(data);
415 free(type);
416 if (background != NULL) {
417 for (i = 0; i < validColumns; i++) {
418 switch (bg_type[bg_colIndex[i]]) {
420 free(bg_data[bg_colIndex[i]].shortData);
421 break;
423 free(bg_data[bg_colIndex[i]].ushortData);
424 break;
426 free(bg_data[bg_colIndex[i]].longData);
427 break;
429 free(bg_data[bg_colIndex[i]].ulongData);
430 break;
432 free(bg_data[bg_colIndex[i]].long64Data);
433 break;
435 free(bg_data[bg_colIndex[i]].ulong64Data);
436 break;
438 free(bg_data[bg_colIndex[i]].floatData);
439 break;
441 free(bg_data[bg_colIndex[i]].doubleData);
442 break;
443 default:
444 continue;
445 }
446 }
447 free(bg_data);
448 free(bg_type);
449 }
450
451 return EXIT_SUCCESS;
452}
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
#define SDDS_STRING
Identifier for the string data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.