96static char *option[N_OPTIONS] = {
115char *USAGE1 =
"Usage: sddsspotanalysis [<input>] [<output>] [-pipe[=in][,out]] \n\
116[-ROI=[{xy}{01}value=<value>][,{xy}{01}parameter=<name>]]\n\
117[-spotROIsize=[{xy}value=<value>][,{xy}parameter=<name>]]\n\
118[-centerOn={{xy}centroid | {xy}peak} | {xy}Parameter=<name>}]\n\
119{-imageColumns=<listOfNames> | -xyz=<ix>,<iy>,<Intensity>} [-singleSpot]\n\
120[-levels=[intensityLevels=<integer>][,saturationLevel=<integer>]]\n\
121[-blankOut=[{xy}{01}value=<value>][,{xy}{01}parameter=<name>]]\n\
122[-sizeLines=[{xy}value=<value>][,{xy}parameter=<name>]]\n\
123[-background=[halfwidth=<value>][,symmetric][,antihalo][,antiloner[,lonerThreshold=<value>]]\n\
124[-despike=[neighbors=<integer>][,passes=<integer>][,averageOf=<integer>][,threshold=<value>][,keep]]\n\
125[-hotpixelFilter=level=<fraction>,distance=<integer>[,passes=<integer>]]\n\
126[-clipNegative] [-spotImage=<filename>] [-majorOrder=row|column] \n\n";
127char *USAGE2 =
"Options:\n"
128 " -pipe[=in][,out] Use the standard SDDS Toolkit pipe option.\n"
129 " -ROI Define the region of interest in pixel units.\n"
130 " All data outside this region is ignored.\n"
131 " -spotROIsize Specify the size in pixels of the ROI around the spot.\n"
132 " This ROI is used for computing spot properties.\n"
133 " -imagecolumns <list> List names of columns containing image data.\n"
134 " Wildcards are supported.\n"
135 " -xyz <ix>,<iy>,<Intensity> Specify columns for x and y pixel indices and intensity.\n"
136 " -singleSpot Eliminate multiple spots by retaining only the most intense connected pixels.\n"
137 " -centerOn <method> Center the analysis on the peak value, centroid, or a specified parameter for both x and y axes.\n"
138 " -levels intensityLevels=<int>, saturationLevel=<int>\n"
139 " Set intensity levels and saturation level.\n"
140 " -blankOut <parameters> Define regions to blank out based on pixel values or parameters.\n"
141 " -sizeLines <parameters> Number of lines to use for analyzing the beam size. Default is 3.\n"
142 " -background <parameters> Configure background subtraction with options like halfwidth, symmetric,\n"
143 " antihalo, antiloner, and lonerThreshold.\n"
144 " -despike <parameters> Apply despiking to smooth the data with options for neighbors, passes,\n"
145 " averageOf, threshold, and keep.\n"
146 " -hotpixelFilter <parameters> Apply a hot pixel filter with level, distance, and passes parameters.\n"
147 " -clipNegative Set negative pixel values to zero.\n"
148 " -spotImage <filename> Specify a file to save images of the spots for plotting with sddscontour.\n"
149 " -majorOrder <row|column> Define the output file order as either row or column.\n\n";
151char *USAGE3 =
"Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
153#define DESPIKE_AVERAGEOF 0x0001U
154#define DESPIKE_KEEP (DESPIKE_AVERAGEOF << 1)
156#define X0VALUE 0x0001U
157#define X1VALUE (X0VALUE << 1)
158#define Y0VALUE (X1VALUE << 1)
159#define Y1VALUE (Y0VALUE << 1)
160#define X0PARAM (Y1VALUE << 1)
161#define X1PARAM (X0PARAM << 1)
162#define Y0PARAM (X1PARAM << 1)
163#define Y1PARAM (Y0PARAM << 1)
164#define OPTGIVEN (Y1PARAM << 1)
168 double backgroundLevel, integratedSpotIntensity, peakSpotIntensity;
169 double saturationCount, backgroundKilledPositive, backgroundKilledNegative;
170 int32_t ROI[4], spotROI[4], spotCenter[2];
171 double spotSigma[2], spotRange50[2], spotRange65[2], spotRange80[2], spotCentroid[2];
172 double S11, S33, rmsCrossProduct, phi, majorAxis, minorAxis;
179 long passes, distance;
182void replaceWithNearNeighbors(
double **image,
long iy0,
long iy1,
long ix0,
long ix1,
long iyc,
long ixc,
long distance);
187 int32_t neighbors, passes, averageOf;
192 long *copyParamNames,
short columnMajorOrder);
193long DetermineQuadLongValues(int32_t *ROI,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long nx,
long ny,
long isROI);
194long DetermineDualLongValues(int32_t *spotROISize,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long defaultValue);
195void BlankOutImageData(
double **image,
long nx,
long ny, int32_t *region);
196long GetImageData(
long *nx,
double ***image,
char **imageColumn,
long ny,
SDDS_DATASET *SDDSin);
197long GetXYZImageData(
long *nx,
long *ny,
double ***image,
char *ixName,
char *iyName,
char *intensityName,
SDDS_DATASET *SDDSin);
199#define SYMMETRIC_BGREMOVAL 0x0001U
200#define ANTIHALO_BGREMOVAL 0x0002U
201#define REMOVE_LONERS 0x0004U
202#define SINGLE_SPOT 0x0008U
203#define XCENTER_PEAK 0x0010U
204#define YCENTER_PEAK 0x0020U
205#define XCENTER_CENTROID 0x0040U
206#define YCENTER_CENTROID 0x0080U
207#define CLIP_NEGATIVE 0x0100U
208#define XCENTER_PARAM 0x0200U
209#define YCENTER_PARAM 0x0400U
211long AnalyzeImageData(
double **image,
long nx,
long ny, int32_t *ROI, int32_t *spotROISize,
213 long intensityLevels,
long saturationLevel,
long backgroundHalfWidth,
long lonerThreshold,
215 double *centerValue);
217void DetermineBeamSizes(
double *sigma,
double *spotRange50,
double *spotRange65,
double *spotRange80,
218 double *lineBuffer,
long i0,
long i1);
219void DetermineBeamParameters(
double **image,
long *spotROI,
long nx,
long ny,
double *S11,
double *S33,
220 double *rmsCrossProduct,
double *phi,
double *majorAxis,
double *minorAxis);
222int main(
int argc,
char **argv) {
224 long iArg, imageColumns = 0, i, ip;
225 char **imageColumn = NULL;
226 char *ixName, *iyName, *IntensityName;
228 unsigned long pipeFlags = 0, ROIFlags = 0, spotROIFlags = 0, blankOutFlags = 0;
229 int32_t intensityLevels = 256, saturationLevel = 254, backgroundHalfWidth = 3, lonerThreshold = 1, lonerPasses = 1;
233 short hotpixelFilter = 0;
234 char *inputFile = NULL, *outputFile = NULL;
235 int32_t ROI[4] = {-1, -1, -1, -1};
236 int32_t spotROISize[2] = {-1, -1};
237 char *ROIParameter[4] = {NULL, NULL, NULL, NULL};
238 int32_t blankOut[4] = {-1, -1, -1, -1};
239 char *blankOutParameter[4] = {NULL, NULL, NULL, NULL};
240 char *spotROISizeParameter[2] = {NULL, NULL};
242 long readStatus, nx, ny, outputRow, maxPages = 0;
245 unsigned long sizeLinesFlags = 0, dummyFlags = 0, backgroundFlags = 0, centerFlags = 0, majorOrderFlag;
246 int32_t sizeLines[2] = {-1, -1};
247 char *sizeLinesParameter[2] = {NULL, NULL};
248 char *centerParameter[2] = {NULL, NULL};
249 double centerValue[2];
250 char **copyParamName;
251 long copyParamNames, copyBuffer[32];
252 char *spotImageFile = NULL;
253 short columnMajorOrder = -1;
257 fprintf(stderr,
"%s%s%s", USAGE1, USAGE2, USAGE3);
261 ixName = iyName = IntensityName = NULL;
264 for (iArg = 1; iArg < argc; iArg++) {
265 if (scArg[iArg].arg_type == OPTION) {
268 switch (
match_string(scArg[iArg].list[0], option, N_OPTIONS, 0)) {
269 case SET_MAJOR_ORDER:
271 scArg[iArg].n_items--;
272 if (scArg[iArg].n_items > 0 &&
273 (!
scanItemList(&majorOrderFlag, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
274 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
275 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
276 SDDS_Bomb(
"invalid -majorOrder syntax/values");
277 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
278 columnMajorOrder = 1;
279 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
280 columnMajorOrder = 0;
282 case SET_IMAGECOLUMNS:
283 if (scArg[iArg].n_items < 2)
284 SDDS_Bomb(
"invalid -imagecolumns syntax");
286 SDDS_Bomb(
"give one and only one -imagecolumns option");
287 imageColumns = scArg[iArg].n_items - 1;
288 imageColumn =
tmalloc(
sizeof(*imageColumn) * imageColumns);
289 for (i = 0; i < imageColumns; i++)
290 imageColumn[i] = scArg[iArg].list[i + 1];
294 if (ROIFlags & OPTGIVEN)
297 scArg[iArg].n_items--;
298 if (scArg[iArg].n_items < 1 ||
299 (!
scanItemList(&ROIFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
300 "x0value",
SDDS_LONG, ROI + 0, 1, X0VALUE,
301 "x1value",
SDDS_LONG, ROI + 1, 1, X1VALUE,
302 "y0value",
SDDS_LONG, ROI + 2, 1, Y0VALUE,
303 "y1value",
SDDS_LONG, ROI + 3, 1, Y1VALUE,
304 "x0parameter",
SDDS_STRING, ROIParameter + 0, 1, X0PARAM,
305 "x1parameter",
SDDS_STRING, ROIParameter + 1, 1, X1PARAM,
306 "y0parameter",
SDDS_STRING, ROIParameter + 2, 1, Y0PARAM,
307 "y1parameter",
SDDS_STRING, ROIParameter + 3, 1, Y1PARAM,
309 ((ROIFlags & X0VALUE) && ROI[0] < 0) || ((ROIFlags & X1VALUE) && ROI[1] < 0) ||
310 ((ROIFlags & Y0VALUE) && ROI[2] < 0) || ((ROIFlags & Y1VALUE) && ROI[3] < 0) ||
311 ((ROIFlags & X0PARAM) && (!ROIParameter[0] || !strlen(ROIParameter[0]))) ||
312 ((ROIFlags & X1PARAM) && (!ROIParameter[1] || !strlen(ROIParameter[1]))) ||
313 ((ROIFlags & Y0PARAM) && (!ROIParameter[2] || !strlen(ROIParameter[2]))) ||
314 ((ROIFlags & Y1PARAM) && (!ROIParameter[3] || !strlen(ROIParameter[3])))))
318 if (blankOutFlags & OPTGIVEN)
320 blankOutFlags = OPTGIVEN;
321 scArg[iArg].n_items--;
322 if (scArg[iArg].n_items < 1 ||
323 (!
scanItemList(&blankOutFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
324 "x0value",
SDDS_LONG, blankOut + 0, 1, X0VALUE,
325 "x1value",
SDDS_LONG, blankOut + 1, 1, X1VALUE,
326 "y0value",
SDDS_LONG, blankOut + 2, 1, Y0VALUE,
327 "y1value",
SDDS_LONG, blankOut + 3, 1, Y1VALUE,
328 "x0parameter",
SDDS_STRING, blankOutParameter + 0, 1, X0PARAM,
329 "x1parameter",
SDDS_STRING, blankOutParameter + 1, 1, X1PARAM,
330 "y0parameter",
SDDS_STRING, blankOutParameter + 2, 1, Y0PARAM,
331 "y1parameter",
SDDS_STRING, blankOutParameter + 3, 1, Y1PARAM,
333 ((blankOutFlags & X0VALUE) && blankOut[0] < 0) || ((blankOutFlags & X1VALUE) && blankOut[1] < 0) ||
334 ((blankOutFlags & Y0VALUE) && blankOut[2] < 0) || ((blankOutFlags & Y1VALUE) && blankOut[3] < 0) ||
335 ((blankOutFlags & X0PARAM) && (!blankOutParameter[0] || !strlen(blankOutParameter[0]))) ||
336 ((blankOutFlags & X1PARAM) && (!blankOutParameter[1] || !strlen(blankOutParameter[1]))) ||
337 ((blankOutFlags & Y0PARAM) && (!blankOutParameter[2] || !strlen(blankOutParameter[2]))) ||
338 ((blankOutFlags & Y1PARAM) && (!blankOutParameter[3] || !strlen(blankOutParameter[3])))))
339 SDDS_Bomb(
"invalid -blankOut syntax/values");
341 case SET_SPOTROISIZE:
342 if (spotROIFlags & OPTGIVEN)
343 SDDS_Bomb(
"give -spotROIsize only once");
344 spotROIFlags = OPTGIVEN;
345 scArg[iArg].n_items--;
346 if (scArg[iArg].n_items < 1 ||
347 (!
scanItemList(&spotROIFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
348 "xvalue",
SDDS_LONG, spotROISize + 0, 1, X0VALUE,
349 "yvalue",
SDDS_LONG, spotROISize + 1, 1, Y0VALUE,
350 "xparameter",
SDDS_STRING, spotROISizeParameter + 0, 1, X0PARAM,
351 "yparameter",
SDDS_STRING, spotROISizeParameter + 1, 1, Y0PARAM,
353 ((spotROIFlags & X0VALUE) && spotROISize[0] < 0) ||
354 ((spotROIFlags & Y0VALUE) && spotROISize[1] < 0) ||
355 ((spotROIFlags & X0PARAM) && (!spotROISizeParameter[0] || !strlen(spotROISizeParameter[0]))) ||
356 ((spotROIFlags & Y0PARAM) && (!spotROISizeParameter[1] || !strlen(spotROISizeParameter[1])))))
357 SDDS_Bomb(
"invalid -spotROIsize syntax/values");
360 if (sizeLinesFlags & OPTGIVEN)
362 sizeLinesFlags = OPTGIVEN;
363 scArg[iArg].n_items--;
364 if (scArg[iArg].n_items < 1 ||
365 (!
scanItemList(&sizeLinesFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
366 "xvalue",
SDDS_LONG, sizeLines + 0, 1, X0VALUE,
367 "yvalue",
SDDS_LONG, sizeLines + 1, 1, Y0VALUE,
368 "xparameter",
SDDS_STRING, sizeLinesParameter + 0, 1, X0PARAM,
369 "yparameter",
SDDS_STRING, sizeLinesParameter + 1, 1, Y0PARAM,
371 ((sizeLinesFlags & X0VALUE) && sizeLines[0] < 0) ||
372 ((sizeLinesFlags & Y0VALUE) && sizeLines[1] < 0) ||
373 ((sizeLinesFlags & X0PARAM) && (!sizeLinesParameter[0] || !strlen(sizeLinesParameter[0]))) ||
374 ((sizeLinesFlags & Y0PARAM) && (!sizeLinesParameter[1] || !strlen(sizeLinesParameter[1])))))
375 SDDS_Bomb(
"invalid -sizeLines syntax/values");
378 scArg[iArg].n_items--;
379 despikeSettings.neighbors = 4;
380 despikeSettings.passes = 1;
381 despikeSettings.threshold = 0;
382 despikeSettings.averageOf = 2;
383 despikeSettings.flags = 0;
384 if (scArg[iArg].n_items > 0 &&
385 (!
scanItemList(&despikeSettings.flags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
386 "neighbors",
SDDS_LONG, &despikeSettings.neighbors, 1, 0,
387 "passes",
SDDS_LONG, &despikeSettings.passes, 1, 0,
388 "averageOf",
SDDS_LONG, &despikeSettings.averageOf, 1, DESPIKE_AVERAGEOF,
389 "threshold",
SDDS_DOUBLE, &despikeSettings.threshold, 1, 0,
390 "keep", -1, NULL, 0, DESPIKE_KEEP, NULL) ||
391 despikeSettings.neighbors < 2 || despikeSettings.passes < 1 ||
392 despikeSettings.averageOf < 2 || despikeSettings.threshold < 0))
393 SDDS_Bomb(
"invalid -despike syntax/values");
394 if (!(despikeSettings.flags & DESPIKE_AVERAGEOF))
395 despikeSettings.averageOf = despikeSettings.neighbors;
396 if (despikeSettings.averageOf > despikeSettings.neighbors)
397 SDDS_Bomb(
"invalid -despike syntax/values: averageOf>neighbors");
401 scArg[iArg].n_items--;
402 hotpixelSettings.passes = 1;
403 hotpixelSettings.distance = 1;
404 hotpixelSettings.fraction = -1;
405 if (scArg[iArg].n_items > 0 &&
406 (!
scanItemList(&hotpixelSettings.flags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
407 "fraction",
SDDS_DOUBLE, &hotpixelSettings.fraction, 1, 0,
408 "passes",
SDDS_LONG, &hotpixelSettings.passes, 1, 0,
409 "distance",
SDDS_LONG, &hotpixelSettings.distance, 1, 0, NULL) ||
410 hotpixelSettings.fraction <= 0 || hotpixelSettings.passes < 1 || hotpixelSettings.distance < 1))
411 SDDS_Bomb(
"invalid -hotpixelFilter syntax/values");
415 if (!
processPipeOption(scArg[iArg].list + 1, scArg[iArg].n_items - 1, &pipeFlags))
419 scArg[iArg].n_items--;
420 if (scArg[iArg].n_items < 1 ||
421 !
scanItemList(&dummyFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
422 "intensityLevels",
SDDS_LONG, &intensityLevels, 1, 0,
423 "saturationLevel",
SDDS_LONG, &saturationLevel, 1, 0, NULL) ||
424 intensityLevels <= 10 || saturationLevel <= 0)
425 SDDS_Bomb(
"invalid -levels syntax/values");
428 scArg[iArg].n_items--;
429 if (scArg[iArg].n_items < 1 ||
430 !
scanItemList(&backgroundFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
431 "halfwidth",
SDDS_LONG, &backgroundHalfWidth, 1, 0,
432 "symmetric", -1, NULL, 0, SYMMETRIC_BGREMOVAL,
433 "antihalo", -1, NULL, 0, ANTIHALO_BGREMOVAL,
434 "antiloner", -1, NULL, 0, REMOVE_LONERS,
435 "lonerthreshold",
SDDS_LONG, &lonerThreshold, 1, 0,
436 "lonerpasses",
SDDS_LONG, &lonerPasses, 1, 0, NULL) ||
437 backgroundHalfWidth < 0)
438 SDDS_Bomb(
"invalid -background syntax/values");
441 if (scArg[iArg].n_items != 1)
442 SDDS_Bomb(
"invalid -singleSpot syntax/values");
443 backgroundFlags |= SINGLE_SPOT;
446 if (scArg[iArg].n_items != 2 || !(spotImageFile = scArg[iArg].list[1]))
447 SDDS_Bomb(
"invalid -spotImage syntax/values");
449 case SET_CLIP_NEGATIVE:
450 backgroundFlags |= CLIP_NEGATIVE;
453 scArg[iArg].n_items--;
455 if (scArg[iArg].n_items < 1 ||
456 !
scanItemList(¢erFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
457 "xcentroid", -1, NULL, 0, XCENTER_CENTROID,
458 "ycentroid", -1, NULL, 0, YCENTER_CENTROID,
459 "xpeak", -1, NULL, 0, XCENTER_PEAK,
460 "ypeak", -1, NULL, 0, YCENTER_PEAK,
461 "xparameter",
SDDS_STRING, centerParameter + 0, 1, XCENTER_PARAM,
462 "yparameter",
SDDS_STRING, centerParameter + 1, 1, YCENTER_PARAM, NULL) ||
463 bitsSet(centerFlags & (XCENTER_CENTROID + XCENTER_PEAK + XCENTER_PARAM)) != 1 ||
464 bitsSet(centerFlags & (YCENTER_CENTROID + YCENTER_PEAK + YCENTER_PARAM)) != 1)
468 if (scArg[iArg].n_items != 4 ||
469 !strlen(ixName = scArg[iArg].list[1]) ||
470 !strlen(iyName = scArg[iArg].list[2]) ||
471 !strlen(IntensityName = scArg[iArg].list[3]))
476 fprintf(stderr,
"unknown option %s given\n", scArg[iArg].list[0]);
483 inputFile = scArg[iArg].list[0];
484 }
else if (!outputFile) {
485 outputFile = scArg[iArg].list[0];
491 processFilenames(
"sddsspotanalysis", &inputFile, &outputFile, pipeFlags, 0, NULL);
493 if (!imageColumns && !IntensityName)
494 SDDS_Bomb(
"you must give either the -imageColumns or -xyz option");
495 if (imageColumns && IntensityName)
496 SDDS_Bomb(
"you must give either the -imageColumns or -xyz option, not both");
504 (!
SDDS_InitializeOutput(&SDDSspim, SDDS_BINARY, 0, NULL,
"sddsspotanalysis spot image", spotImageFile) ||
517 if ((imageColumns = expandColumnPairNames(&SDDSin, &imageColumn, NULL, imageColumns, NULL, 0, FIND_NUMERIC_TYPE, 0)) <= 0) {
519 SDDS_Bomb(
"No quantities selected to analyze");
523 if (!(image = calloc(ny,
sizeof(*image))))
529 if (!SetUpOutputFile(&SDDSout, outputFile, &SDDSin, ©ParamName, ©ParamNames, columnMajorOrder) ||
531 SDDS_Bomb(
"Problem setting up output file.");
534 if (readStatus > maxPages) {
536 SDDS_Bomb(
"Problem lengthening output file.");
543 if (!GetImageData(&nx, &image, imageColumn, ny, &SDDSin))
544 SDDS_Bomb(
"Problem getting image data.");
548 if (!GetXYZImageData(&nx, &ny, &image, ixName, iyName, IntensityName, &SDDSin))
549 SDDS_Bomb(
"Problem getting image data.");
553 if (!DetermineQuadLongValues(ROI, ROIFlags, ROIParameter, &SDDSin, nx, ny, 1)) {
555 SDDS_Bomb(
"Problem determining region of interest---verify that you gave sufficient information.");
557 if (blankOutFlags && !DetermineQuadLongValues(blankOut, blankOutFlags, blankOutParameter, &SDDSin, nx, ny, 0))
558 SDDS_Bomb(
"Problem determining blankout region---verify that you gave sufficient information.");
559 if (!DetermineDualLongValues(spotROISize, spotROIFlags, spotROISizeParameter, &SDDSin, 150))
560 SDDS_Bomb(
"Problem determine size of spot region of interest---verify that you gave sufficient information.");
561 if (!DetermineDualLongValues(sizeLines, sizeLinesFlags, sizeLinesParameter, &SDDSin, 3))
562 SDDS_Bomb(
"Problem determine size of number of lines to use for spot size computation---verify that you gave sufficient information.");
563 centerValue[0] = centerValue[1] = -1;
565 SDDS_Bomb(
"Problem getting center parameter value for x.");
567 SDDS_Bomb(
"Problem getting center parameter value for y.");
569 BlankOutImageData(image, nx, ny, blankOut);
570 if (!AnalyzeImageData(image, nx, ny, ROI, spotROISize, sizeLines,
571 despike ? &despikeSettings : NULL, hotpixelFilter ? &hotpixelSettings : NULL, intensityLevels,
572 saturationLevel, backgroundHalfWidth, lonerThreshold, lonerPasses, backgroundFlags | centerFlags,
573 &analysisResults, spotImageFile ? &SDDSspim : NULL, centerValue))
575 for (ip = 0; ip < copyParamNames; ip++) {
577 SDDS_Bomb(
"Problem reading parameter data from input file.");
578 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, outputRow, copyParamName[ip], copyBuffer, NULL)) {
579 SDDS_Bomb(
"Problem copying parameter data from input file.");
582 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, outputRow++,
583 "ImageIndex", readStatus - 1,
584 "xROILower", analysisResults.ROI[0],
585 "xROIUpper", analysisResults.ROI[1],
586 "yROILower", analysisResults.ROI[2],
587 "yROIUpper", analysisResults.ROI[3],
588 "xSpotROILower", analysisResults.spotROI[0],
589 "xSpotROIUpper", analysisResults.spotROI[1],
590 "ySpotROILower", analysisResults.spotROI[2],
591 "ySpotROIUpper", analysisResults.spotROI[3],
592 "xSpotCenter", analysisResults.spotCenter[0],
593 "ySpotCenter", analysisResults.spotCenter[1],
594 "xSpotCentroid", analysisResults.spotCentroid[0],
595 "ySpotCentroid", analysisResults.spotCentroid[1],
596 "xSpotSigma", analysisResults.spotSigma[0],
597 "xSpotRange50", analysisResults.spotRange50[0],
598 "xSpotRange65", analysisResults.spotRange65[0],
599 "xSpotRange80", analysisResults.spotRange80[0],
600 "ySpotSigma", analysisResults.spotSigma[1],
601 "ySpotRange50", analysisResults.spotRange50[1],
602 "ySpotRange65", analysisResults.spotRange65[1],
603 "ySpotRange80", analysisResults.spotRange80[1],
604 "BackgroundLevel", analysisResults.backgroundLevel,
605 "BackgroundKilledPositive", analysisResults.backgroundKilledPositive,
606 "BackgroundKilledNegative", analysisResults.backgroundKilledNegative,
607 "IntegratedSpotIntensity", analysisResults.integratedSpotIntensity,
608 "PeakSpotIntensity", analysisResults.peakSpotIntensity,
609 "SaturationCount", analysisResults.saturationCount,
610 "phi", analysisResults.phi,
611 "rmsCrossProduct", analysisResults.rmsCrossProduct,
612 "majorAxis", analysisResults.majorAxis,
613 "minorAxis", analysisResults.minorAxis,
614 "S11", analysisResults.S11,
615 "S33", analysisResults.S33,
616 "S13", analysisResults.rmsCrossProduct, NULL)) {
625 for (i = 0; i < ny; i++)
628 for (i = 0; i < ny; i++)
629 free(imageColumn[i]);
632 for (i = 0; i < copyParamNames; i++)
633 free(copyParamName[i]);
640 long *copyParamNames,
short columnMajorOrder) {
683 if (columnMajorOrder != -1)
684 SDDSout->layout.data_mode.column_major = columnMajorOrder;
686 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
689 *copyParamName = NULL;
692 if (!(*copyParamName = calloc(
sizeof(**copyParamName), paramNames)))
694 for (ip = 0; ip < paramNames; ip++) {
704 (*copyParamName)[*copyParamNames] = paramName[ip];
717long DetermineQuadLongValues(int32_t *ROI,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long nx,
long ny,
long isROI) {
720 double defaultROI[4];
722 defaultROI[0] = defaultROI[2] = 0;
723 defaultROI[1] = nx - 1;
724 defaultROI[3] = ny - 1;
726 defaultROI[0] = defaultROI[2] = defaultROI[1] = defaultROI[3] = -1;
727 for (i = 0; i < 4; i++) {
728 if (flags & (X0VALUE << i))
730 if (flags & (X0PARAM << i)) {
735 ROI[i] = value + 0.5;
737 ROI[i] = defaultROI[i];
739 if (ROI[0] < 0 || ROI[2] < 0) {
743 if (ROI[1] > nx - 1 || ROI[3] > ny - 1) {
747 if (ROI[0] >= ROI[1]) {
751 if (ROI[2] >= ROI[3]) {
758long DetermineDualLongValues(int32_t *returnValue,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long defaultValue) {
762 for (i = 0; i < 2; i++) {
763 if (flags & (X0VALUE << (2 * i)))
765 if (flags & (X0PARAM << (2 * i))) {
770 returnValue[i] = (int32_t)value;
772 returnValue[i] = defaultValue;
774 if (returnValue[0] <= 0 || returnValue[1] <= 0) {
781long GetImageData(
long *nx,
double ***image,
char **imageColumn,
long ny,
SDDS_DATASET *SDDSin) {
788 for (i = 0; i < ny; i++) {
794 SDDS_Bomb(
"Unable to get data from columns");
797 *nx = SDDS_RowCount(SDDSin);
801long GetXYZImageData(
long *nx,
long *ny,
double ***image,
char *ixName,
char *iyName,
char *intensityName,
SDDS_DATASET *SDDSin) {
802 int32_t *ixData, *iyData;
803 double *intensityData;
804 long ixMin, iyMin, ixMax, iyMax, i, ix, iy, nRows;
805 char *ixIndexCheck, *iyIndexCheck;
807 if ((nRows = SDDS_RowCount(SDDSin)) <= 0 ||
813 ixMax = iyMax = -(ixMin = iyMin = LONG_MAX);
815 for (i = 0; i < nRows; i++) {
816 if (ixMax < ixData[i])
818 if (ixMin > ixData[i])
820 if (iyMax < iyData[i])
822 if (iyMin > iyData[i])
830 ixIndexCheck = calloc((*nx = ixMax - ixMin + 1),
sizeof(*ixIndexCheck));
831 iyIndexCheck = calloc((*ny = iyMax - iyMin + 1),
sizeof(*iyIndexCheck));
833 *image = calloc(*ny,
sizeof(**image));
834 for (iy = 0; iy < *ny; iy++)
835 (*image)[iy] = calloc(*nx,
sizeof(***image));
837 for (i = 0; i < nRows; i++) {
838 ix = ixData[i] - ixMin;
839 iy = iyData[i] - iyMin;
840 ixIndexCheck[ix] = 1;
841 iyIndexCheck[iy] = 1;
842 (*image)[iy][ix] = intensityData[i];
845 for (i = 0; i <= (ixMax - ixMin); i++) {
846 if (!ixIndexCheck[i]) {
847 fprintf(stderr,
"Error: image file is missing some x index values\n");
849 for (
long y = 0; y < *ny; y++) {
861 for (i = 0; i <= (iyMax - iyMin); i++) {
862 if (!iyIndexCheck[i]) {
863 fprintf(stderr,
"Error: image file is missing some y index values\n");
865 for (
long y = 0; y < *ny; y++) {
887long AnalyzeImageData(
double **image,
long nx,
long ny, int32_t *ROI, int32_t *spotROISize, int32_t *sizeLines,
889 long intensityLevels,
long saturationLevel,
long backgroundHalfWidth,
long lonerThreshold,
890 long lonerPasses,
unsigned long flags,
IMAGE_ANALYSIS *analysisResults,
892 long ix, iy, iy0, iy1, ix0, ix1, nxROI, nyROI;
893 double maxValue, minValue, background, value, sum1, sum2;
894 long ixCenter, iyCenter;
895 int64_t ixMax, ixMin;
897 double *intensityHistogram, *lineBuffer = NULL, *x = NULL, *y = NULL;
917 if (ROI[0] >= 0 && ROI[1] >= 0 && ROI[0] < ROI[1]) {
926 nxROI = ix1 - ix0 + 1;
928 if (ROI[2] >= 0 && ROI[3] >= 0 && ROI[2] < ROI[3]) {
937 nyROI = iy1 - iy0 + 1;
939 if ((nyROI) < spotROISize[1] || (nxROI) < spotROISize[0])
940 SDDS_Bomb(
"spot ROI is larger than ROI");
944 if (!(lineBuffer =
SDDS_Malloc(
sizeof(*lineBuffer) * (nx > ny ? nx : ny))))
948 ixCenter = iyCenter = -1;
950 for (ix = ix0; ix <= ix1; ix++) {
951 for (iy = iy0; iy <= iy1; iy++) {
952 if ((flags & CLIP_NEGATIVE) && image[iy][ix] < 0)
954 if (image[iy][ix] < 0 || image[iy][ix] >= intensityLevels)
955 SDDS_Bomb(
"image intensity outside intensity level range");
959 if (despikeSettings && (despikeSettings->flags & DESPIKE_KEEP)) {
961 for (ix = ix0; ix <= ix1; ix++) {
962 for (iy = iy0; iy <= iy1; iy++)
963 lineBuffer[iy - iy0] = image[iy][ix];
964 despikeData(lineBuffer, nyROI, despikeSettings->neighbors, despikeSettings->passes, despikeSettings->averageOf,
965 despikeSettings->threshold, 0);
966 for (iy = iy0; iy <= iy1; iy++)
967 image[iy][ix] = lineBuffer[iy - iy0];
972 for (iy = iy0; iy <= iy1; iy++) {
973 if (despikeSettings) {
974 memcpy(lineBuffer, image[iy] + ix0, nxROI *
sizeof(*lineBuffer));
975 despikeData(lineBuffer, nxROI, despikeSettings->neighbors, despikeSettings->passes, despikeSettings->averageOf,
976 despikeSettings->threshold, 0);
977 if (despikeSettings->flags & DESPIKE_KEEP)
978 memcpy(image[iy] + ix0, lineBuffer, nxROI *
sizeof(*lineBuffer));
980 lineBuffer = image[iy] + ix0;
982 if (lineBuffer[ixMax] > maxValue) {
983 maxValue = lineBuffer[ixMax];
984 ixCenter = ixMax + ix0;
987 if (lineBuffer[ixMin] < minValue)
988 minValue = lineBuffer[ixMin];
990 if (despikeSettings) {
994 if (flags & XCENTER_PARAM)
995 ixCenter = centerValue[0];
997 centerValue[0] = ixCenter;
998 if (flags & YCENTER_PARAM)
999 iyCenter = centerValue[1];
1001 centerValue[1] = iyCenter;
1002 if (ixCenter == -1 || iyCenter == -1)
1006 if (!(intensityHistogram = calloc(intensityLevels,
sizeof(*intensityHistogram))))
1008 for (iy = iy0; iy <= iy1; iy++)
1009 make_histogram(intensityHistogram, intensityLevels, -0.5, intensityLevels + 0.5, image[iy] + ix0, nxROI, iy == iy0);
1010 index_min_max(&ixMin, &ixMax, intensityHistogram, intensityLevels);
1012 for (i = ixMax - backgroundHalfWidth; i <= ixMax + backgroundHalfWidth; i++) {
1013 if (i < 0 || i >= intensityLevels)
1015 sum1 += intensityHistogram[i];
1016 sum2 += intensityHistogram[i] * i;
1019 background = sum2 / sum1;
1024 free(intensityHistogram);
1026 if (hotpixelSettings) {
1027 long min, max, pass;
1033 pass = hotpixelSettings->passes;
1035 max = -(min = LONG_MAX);
1036 for (iy = iy0; iy <= iy1; iy++) {
1037 for (ix = ix0; ix <= ix1; ix++) {
1038 if (image[iy][ix] > max)
1039 max = image[iy][ix];
1040 if (image[iy][ix] < min)
1041 min = image[iy][ix];
1045 SDDS_Bomb(
"Can't apply hotpixel filter (min=max). Are data non-integer?");
1046 for (iy = iy0; iy <= iy1; iy++)
1047 for (ix = ix0; ix <= ix1; ix++)
1048 if ((image[iy][ix] - min) > (max - min) * hotpixelSettings->fraction)
1049 replaceWithNearNeighbors(image, iy0, iy1, ix0, ix1, iy, ix, hotpixelSettings->distance);
1054 if (flags & XCENTER_CENTROID) {
1056 for (ix = ix0; ix <= ix1; ix++)
1057 for (iy = iy0; iy <= iy1; iy++) {
1058 sum += image[iy][ix];
1059 mean += image[iy][ix] * ix;
1062 spotROI[0] = mean - spotROISize[0] / 2;
1064 spotROI[0] = ixCenter - spotROISize[0] / 2;
1066 spotROI[1] = spotROI[0] + spotROISize[0] - 1;
1067 if (spotROI[0] < ix0) {
1069 spotROI[1] = ix0 + spotROISize[0] - 1;
1070 }
else if (spotROI[1] > ix1) {
1072 spotROI[0] = ix1 - spotROISize[0] + 1;
1074 if (spotROI[0] < ix0 || spotROI[1] > ix1)
1075 SDDS_Bomb(
"spot ROI is larger than ROI for x");
1077 if (flags & XCENTER_CENTROID) {
1079 for (ix = ix0; ix <= ix1; ix++)
1080 for (iy = iy0; iy <= iy1; iy++) {
1081 sum += image[iy][ix];
1082 mean += image[iy][ix] * iy;
1085 spotROI[2] = mean - spotROISize[1] / 2;
1087 spotROI[2] = iyCenter - spotROISize[1] / 2;
1090 spotROI[3] = spotROI[2] + spotROISize[1] - 1;
1091 if (spotROI[2] < iy0) {
1093 spotROI[3] = iy0 + spotROISize[1] - 1;
1094 }
else if (spotROI[3] > iy1) {
1096 spotROI[2] = iy1 - spotROISize[1] + 1;
1098 if (spotROI[2] < iy0 || spotROI[3] > iy1)
1099 SDDS_Bomb(
"spot ROI is larger than ROI for y");
1102 analysisResults->saturationCount = 0;
1103 analysisResults->integratedSpotIntensity = 0;
1104 analysisResults->backgroundKilledNegative = 0;
1105 analysisResults->backgroundKilledPositive = 0;
1106 saturationLevel -= (long)background;
1107 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1108 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1109 if ((value = image[iy][ix] - background) <= 0) {
1110 analysisResults->backgroundKilledNegative += 1;
1113 image[iy][ix] = value;
1116 if (flags & SYMMETRIC_BGREMOVAL) {
1117 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1118 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1119 long ox, oy, goodPixels;
1120 long ox0, ox1, oy0, oy1;
1121 if (image[iy][ix] > 0 && image[iy][ix] <= backgroundHalfWidth) {
1125 ox0 = (ix == spotROI[0] ? 0 : -1);
1126 ox1 = (ix == spotROI[1] ? 0 : 1);
1127 oy0 = (iy == spotROI[2] ? 0 : -1);
1128 oy1 = (iy == spotROI[3] ? 0 : 1);
1131 goodPixels = (ox1 - ox0 + 1) * (oy1 - oy0 + 1);
1132 for (ox = ox0; ox <= ox1; ox++) {
1133 for (oy = oy0; oy <= oy1; oy++) {
1134 if (image[iy + oy][ix + ox] <= backgroundHalfWidth)
1138 if (goodPixels <= 1) {
1139 analysisResults->backgroundKilledPositive += 1;
1146 if (flags & REMOVE_LONERS) {
1147 while (lonerPasses-- > 0) {
1148 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1149 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1150 long ox, oy, company;
1151 long ox0, ox1, oy0, oy1;
1152 if (image[iy][ix] > 0) {
1155 ox0 = (ix == spotROI[0] ? 0 : -1);
1156 ox1 = (ix == spotROI[1] ? 0 : 1);
1157 oy0 = (iy == spotROI[2] ? 0 : -1);
1158 oy1 = (iy == spotROI[3] ? 0 : 1);
1161 company = (ox1 - ox0 + 1) * (oy1 - oy0 + 1);
1162 for (ox = ox0; ox <= ox1; ox++) {
1163 for (oy = oy0; oy <= oy1; oy++) {
1164 if (image[iy + oy][ix + ox] == 0)
1168 if (company <= lonerThreshold) {
1169 analysisResults->backgroundKilledPositive += 1;
1177 if (flags & ANTIHALO_BGREMOVAL) {
1179 for (tryCount = 0; tryCount < 2; tryCount++) {
1180 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1181 for (iy = spotROI[2]; iy < spotROI[3]; iy++) {
1182 if (image[iy][ix] > backgroundHalfWidth || image[iy + 1][ix] > backgroundHalfWidth)
1184 if (image[iy][ix]) {
1186 analysisResults->backgroundKilledPositive += 1;
1189 if (iy != spotROI[3])
1190 for (iy = spotROI[3]; iy > spotROI[2]; iy--) {
1191 if (image[iy][ix] > backgroundHalfWidth || image[iy - 1][ix] > backgroundHalfWidth)
1193 if (image[iy][ix]) {
1195 analysisResults->backgroundKilledPositive += 1;
1199 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1200 for (ix = spotROI[0]; ix < spotROI[1]; ix++) {
1201 if (image[iy][ix] > backgroundHalfWidth || image[iy][ix + 1] > backgroundHalfWidth)
1203 if (image[iy][ix]) {
1205 analysisResults->backgroundKilledPositive += 1;
1208 if (ix != spotROI[1])
1209 for (ix = spotROI[1]; ix > spotROI[0]; ix--) {
1210 if (image[iy][ix] > backgroundHalfWidth || image[iy][ix - 1] > backgroundHalfWidth)
1212 if (image[iy][ix]) {
1214 analysisResults->backgroundKilledPositive += 1;
1220 if (flags & SINGLE_SPOT) {
1221 short **connected, changed;
1223 long ix_max = 0, iy_max = 0;
1225 connected =
tmalloc(
sizeof(*connected) * nx);
1226 for (ix = 0; ix < nx; ix++)
1227 connected[ix] =
tmalloc(
sizeof(**connected) * ny);
1229 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1230 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1231 connected[ix][iy] = 0;
1232 if (image[iy][ix] > maxVal) {
1235 maxVal = image[iy][ix];
1238 connected[ix_max][iy_max] = 1;
1242 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1243 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1244 if (!image[iy][ix] || connected[ix][iy])
1246 if (ix > spotROI[0] && connected[ix - 1][iy]) {
1247 changed += (connected[ix][iy] = 1);
1250 if (ix < spotROI[1] && connected[ix + 1][iy]) {
1251 changed += (connected[ix][iy] = 1);
1254 if (iy > spotROI[2] && connected[ix][iy - 1]) {
1255 changed += (connected[ix][iy] = 1);
1258 if (iy < spotROI[3] && connected[ix][iy + 1]) {
1259 changed += (connected[ix][iy] = 1);
1263 for (ix = spotROI[1]; ix >= spotROI[0]; ix--)
1264 for (iy = spotROI[3]; iy >= spotROI[2]; iy--) {
1265 if (!image[iy][ix] || connected[ix][iy])
1267 if (ix > spotROI[0] && connected[ix - 1][iy]) {
1268 changed += (connected[ix][iy] = 1);
1271 if (ix < spotROI[1] && connected[ix + 1][iy]) {
1272 changed += (connected[ix][iy] = 1);
1275 if (iy > spotROI[2] && connected[ix][iy - 1]) {
1276 changed += (connected[ix][iy] = 1);
1279 if (iy < spotROI[3] && connected[ix][iy + 1]) {
1280 changed += (connected[ix][iy] = 1);
1286 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1287 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1288 if (!connected[ix][iy])
1292 for (ix = 0; ix < nx; ix++) {
1293 free(connected[ix]);
1299 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1300 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1301 if (image[iy][ix] > saturationLevel)
1302 analysisResults->saturationCount += 1;
1305 analysisResults->spotCentroid[0] = analysisResults->spotCentroid[1] = 0;
1306 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1307 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1308 analysisResults->integratedSpotIntensity += image[iy][ix];
1309 analysisResults->spotCentroid[0] += image[iy][ix] * ix;
1310 analysisResults->spotCentroid[1] += image[iy][ix] * iy;
1312 if (analysisResults->integratedSpotIntensity)
1313 for (i = 0; i < 2; i++)
1314 analysisResults->spotCentroid[i] /= analysisResults->integratedSpotIntensity;
1317 if (!(lineBuffer = calloc(ny,
sizeof(*lineBuffer))))
1319 if (!(x = calloc(ny,
sizeof(*x))))
1321 if (!(y = calloc(ny,
sizeof(*y))))
1323 for (ix = ixCenter - sizeLines[0] / 2; ix <= ixCenter + sizeLines[0] / 2; ix++) {
1324 if (ix < ix0 || ix > ix1)
1326 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1327 lineBuffer[iy] += image[iy][ix];
1329 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1330 y[iy] = lineBuffer[iy];
1332 DetermineBeamSizes(&analysisResults->spotSigma[1], &analysisResults->spotRange50[1], &analysisResults->spotRange65[1],
1333 &analysisResults->spotRange80[1], lineBuffer, spotROI[2], spotROI[3]);
1336 if (!(lineBuffer = calloc(nx,
sizeof(*lineBuffer))))
1338 for (iy = iyCenter - sizeLines[1] / 2; iy <= iyCenter + sizeLines[1] / 2; iy++) {
1339 if (iy < iy0 || iy > iy1)
1341 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1342 lineBuffer[ix] += image[iy][ix];
1344 DetermineBeamSizes(&analysisResults->spotSigma[0], &analysisResults->spotRange50[0], &analysisResults->spotRange65[0],
1345 &analysisResults->spotRange80[0], lineBuffer, spotROI[0], spotROI[1]);
1347 DetermineBeamParameters(image, spotROI, nx, ny, &analysisResults->S11, &analysisResults->S33, &analysisResults->rmsCrossProduct,
1348 &analysisResults->phi, &analysisResults->majorAxis, &analysisResults->minorAxis);
1350 analysisResults->peakSpotIntensity = maxValue - background;
1351 analysisResults->spotCenter[0] = ixCenter;
1352 analysisResults->spotCenter[1] = iyCenter;
1353 analysisResults->backgroundLevel = background;
1354 analysisResults->ROI[0] = ix0;
1355 analysisResults->ROI[1] = ix1;
1356 analysisResults->ROI[2] = iy0;
1357 analysisResults->ROI[3] = iy1;
1358 for (i = 0; i < 4; i++)
1359 analysisResults->spotROI[i] = spotROI[i];
1367 if (!
SDDS_StartPage(SDDSspim, (spotROI[1] - spotROI[0] + 1) * (spotROI[3] - spotROI[2] + 1)))
1368 SDDS_Bomb(
"Problem starting page for spot image output file.");
1369 if (!
SDDS_SetParameters(SDDSspim, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
"nx", (
short)(spotROI[1] - spotROI[0] + 1),
1370 "ny", (
short)(spotROI[3] - spotROI[2] + 1), NULL))
1371 SDDS_Bomb(
"Problem setting parameter values for spot image output file.");
1373 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1374 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1375 if (!
SDDS_SetRowValues(SDDSspim, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, i_row++,
"ix", (
short)ix,
1376 "iy", (
short)iy,
"Image", image[iy][ix], NULL)) {
1377 SDDS_Bomb(
"Problem setting row values for spot image output file.");
1382 SDDS_Bomb(
"Problem writing page for spot image output file.");
1388void DetermineBeamSizes(
double *sigma,
double *Range50,
double *Range65,
double *Range80,
double *lineBuffer,
long i0,
long i1) {
1389 double centroid, sum;
1391 double pLevel[6] = {.10, .175, .25, .75, .825, .90};
1395 *sigma = *Range80 = *Range65 = *Range50 = 0;
1396 for (i = i0; i <= i1; i++) {
1397 sum += lineBuffer[i];
1398 centroid += lineBuffer[i] * i;
1401 centroid = centroid / sum;
1402 for (i = i0; i <= i1; i++)
1403 *sigma += lineBuffer[i] * sqr(i - centroid);
1404 *sigma = sqrt(*sigma / sum);
1407 for (i = i0 + 1; i <= i1; i++)
1408 lineBuffer[i] += lineBuffer[i - 1];
1409 if (lineBuffer[i1]) {
1410 for (i = i0; i <= i1; i++)
1411 lineBuffer[i] /= lineBuffer[i1];
1413 for (j = 0; j < 6; j++) {
1415 while (i <= i1 && lineBuffer[i] < pLevel[j])
1419 }
else if (lineBuffer[i] == lineBuffer[i - 1])
1420 pValue[j] = i - 0.5;
1422 pValue[j] = i - (lineBuffer[i] - pLevel[j]) / (lineBuffer[i] - lineBuffer[i - 1]);
1424 *Range80 = pValue[5] - pValue[0];
1425 *Range65 = pValue[4] - pValue[1];
1426 *Range50 = pValue[3] - pValue[2];
1431void BlankOutImageData(
double **image,
long nx,
long ny, int32_t *region) {
1432 long ix, iy, count = 0;
1433 for (ix = region[0]; ix <= region[1]; ix++)
1434 for (iy = region[2]; iy <= region[3]; iy++, count++)
1438void DetermineBeamParameters(
double **image,
long *spotROI,
long nx,
long ny,
double *S11,
double *S33,
1439 double *rmsCrossProduct,
double *phi,
double *majorAxis,
double *minorAxis) {
1441 long x1, x2, y1, y2;
1442 double imageArea = 0, x2Ave = 0, y2Ave = 0, xyAve = 0, dominator = 0, xcentroid = 0, ycentroid = 0;
1450 for (i = y1; i <= y2; i++)
1451 for (j = x1; j <= x2; j++) {
1452 imageArea += image[i][j];
1453 xcentroid += image[i][j] * j;
1454 ycentroid += image[i][j] * i;
1456 if (imageArea == 0) {
1457 *rmsCrossProduct = *majorAxis = *minorAxis = DBL_MAX;
1459 xcentroid = xcentroid / imageArea;
1460 ycentroid = ycentroid / imageArea;
1461 for (i = y1; i <= y2; i++)
1462 for (j = x1; j <= x2; j++) {
1463 x2Ave += sqr(j - xcentroid) * image[i][j];
1464 y2Ave += sqr(i - ycentroid) * image[i][j];
1465 xyAve += (i - ycentroid) * (j - xcentroid) * image[i][j];
1467 x2Ave = x2Ave / imageArea;
1468 y2Ave = y2Ave / imageArea;
1469 xyAve = xyAve / imageArea;
1470 dominator = x2Ave * y2Ave - xyAve * xyAve;
1473 *rmsCrossProduct = xyAve;
1474 *phi = 0.5 * atan2(2 * xyAve, x2Ave - y2Ave) / PI * 180;
1475 if ((x2Ave + y2Ave - sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))) != 0) {
1476 *majorAxis = sqrt(2 * dominator / (x2Ave + y2Ave - sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))));
1478 *majorAxis = DBL_MAX;
1480 if ((x2Ave + y2Ave + sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))) != 0) {
1481 *minorAxis = sqrt(2 * dominator / (x2Ave + y2Ave + sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))));
1483 *minorAxis = DBL_MAX;
1488void replaceWithNearNeighbors(
double **image,
long iy0,
long iy1,
long ix0,
long ix1,
long iyc,
long ixc,
long distance) {
1492 if ((iyc - distance) > iy0)
1493 iy0 = iyc - distance;
1494 if ((iyc + distance) < iy1)
1495 iy1 = iyc + distance;
1497 if ((ixc - distance) > ix0)
1498 ix0 = ixc - distance;
1499 if ((ixc + distance) < ix1)
1500 ix1 = ixc + distance;
1504 for (iy = iy0; iy <= iy1; iy++)
1505 for (ix = ix0; ix <= ix1; ix++) {
1506 if (ix == ixc && iy == iyc)
1508 sum += image[iy][ix];
1513 image[iyc][ixc] = sum / nnn;
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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.
int32_t SDDS_DefineColumnLikeParameter(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a column in the target dataset based on a parameter definition from the source dataset.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
Utility functions for SDDS dataset manipulation and string array operations.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
int index_min_max(int64_t *imin, int64_t *imax, double *list, int64_t n)
Finds the indices of the minimum and maximum values in a list of doubles.
long make_histogram(double *hist, long n_bins, double lo, double hi, double *data, int64_t n_pts, long new_start)
Compiles a histogram from data points.
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 scanargsg(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.
long despikeData(double *data, long rows, long neighbors, long passes, long averageOf, double threshold, long countLimit)
Remove spikes from a data array by comparing each point to its neighbors.