71static char *option[N_OPTIONS] = {
90char *USAGE1 =
"Usage: sddsspotanalysis [<input>] [<output>] [-pipe[=in][,out]] \n\
91[-ROI=[{xy}{01}value=<value>][,{xy}{01}parameter=<name>]]\n\
92[-spotROIsize=[{xy}value=<value>][,{xy}parameter=<name>]]\n\
93[-centerOn={{xy}centroid | {xy}peak} | {xy}Parameter=<name>}]\n\
94{-imageColumns=<listOfNames> | -xyz=<ix>,<iy>,<Intensity>} [-singleSpot]\n\
95[-levels=[intensityLevels=<integer>][,saturationLevel=<integer>]]\n\
96[-blankOut=[{xy}{01}value=<value>][,{xy}{01}parameter=<name>]]\n\
97[-sizeLines=[{xy}value=<value>][,{xy}parameter=<name>]]\n\
98[-background=[halfwidth=<value>][,symmetric][,antihalo][,antiloner[,lonerThreshold=<value>]]\n\
99[-despike=[neighbors=<integer>][,passes=<integer>][,averageOf=<integer>][,threshold=<value>][,keep]]\n\
100[-hotpixelFilter=level=<fraction>,distance=<integer>[,passes=<integer>]]\n\
101[-clipNegative] [-spotImage=<filename>] [-majorOrder=row|column] \n\n";
102char *USAGE2 =
"Options:\n"
103 " -pipe[=in][,out] Use the standard SDDS Toolkit pipe option.\n"
104 " -ROI Define the region of interest in pixel units.\n"
105 " All data outside this region is ignored.\n"
106 " -spotROIsize Specify the size in pixels of the ROI around the spot.\n"
107 " This ROI is used for computing spot properties.\n"
108 " -imagecolumns <list> List names of columns containing image data.\n"
109 " Wildcards are supported.\n"
110 " -xyz <ix>,<iy>,<Intensity> Specify columns for x and y pixel indices and intensity.\n"
111 " -singleSpot Eliminate multiple spots by retaining only the most intense connected pixels.\n"
112 " -centerOn <method> Center the analysis on the peak value, centroid, or a specified parameter for both x and y axes.\n"
113 " -levels intensityLevels=<int>, saturationLevel=<int>\n"
114 " Set intensity levels and saturation level.\n"
115 " -blankOut <parameters> Define regions to blank out based on pixel values or parameters.\n"
116 " -sizeLines <parameters> Number of lines to use for analyzing the beam size. Default is 3.\n"
117 " -background <parameters> Configure background subtraction with options like halfwidth, symmetric,\n"
118 " antihalo, antiloner, and lonerThreshold.\n"
119 " -despike <parameters> Apply despiking to smooth the data with options for neighbors, passes,\n"
120 " averageOf, threshold, and keep.\n"
121 " -hotpixelFilter <parameters> Apply a hot pixel filter with level, distance, and passes parameters.\n"
122 " -clipNegative Set negative pixel values to zero.\n"
123 " -spotImage <filename> Specify a file to save images of the spots for plotting with sddscontour.\n"
124 " -majorOrder <row|column> Define the output file order as either row or column.\n\n";
126char *USAGE3 =
"Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
128#define DESPIKE_AVERAGEOF 0x0001U
129#define DESPIKE_KEEP (DESPIKE_AVERAGEOF << 1)
131#define X0VALUE 0x0001U
132#define X1VALUE (X0VALUE << 1)
133#define Y0VALUE (X1VALUE << 1)
134#define Y1VALUE (Y0VALUE << 1)
135#define X0PARAM (Y1VALUE << 1)
136#define X1PARAM (X0PARAM << 1)
137#define Y0PARAM (X1PARAM << 1)
138#define Y1PARAM (Y0PARAM << 1)
139#define OPTGIVEN (Y1PARAM << 1)
143 double backgroundLevel, integratedSpotIntensity, peakSpotIntensity;
144 double saturationCount, backgroundKilledPositive, backgroundKilledNegative;
145 int32_t ROI[4], spotROI[4], spotCenter[2];
146 double spotSigma[2], spotRange50[2], spotRange65[2], spotRange80[2], spotCentroid[2];
147 double S11, S33, rmsCrossProduct, phi, majorAxis, minorAxis;
154 long passes, distance;
157void replaceWithNearNeighbors(
double **image,
long iy0,
long iy1,
long ix0,
long ix1,
long iyc,
long ixc,
long distance);
162 int32_t neighbors, passes, averageOf;
167 long *copyParamNames,
short columnMajorOrder);
168long DetermineQuadLongValues(int32_t *ROI,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long nx,
long ny,
long isROI);
169long DetermineDualLongValues(int32_t *spotROISize,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long defaultValue);
170void BlankOutImageData(
double **image,
long nx,
long ny, int32_t *region);
171long GetImageData(
long *nx,
double ***image,
char **imageColumn,
long ny,
SDDS_DATASET *SDDSin);
172long GetXYZImageData(
long *nx,
long *ny,
double ***image,
char *ixName,
char *iyName,
char *intensityName,
SDDS_DATASET *SDDSin);
174#define SYMMETRIC_BGREMOVAL 0x0001U
175#define ANTIHALO_BGREMOVAL 0x0002U
176#define REMOVE_LONERS 0x0004U
177#define SINGLE_SPOT 0x0008U
178#define XCENTER_PEAK 0x0010U
179#define YCENTER_PEAK 0x0020U
180#define XCENTER_CENTROID 0x0040U
181#define YCENTER_CENTROID 0x0080U
182#define CLIP_NEGATIVE 0x0100U
183#define XCENTER_PARAM 0x0200U
184#define YCENTER_PARAM 0x0400U
186long AnalyzeImageData(
double **image,
long nx,
long ny, int32_t *ROI, int32_t *spotROISize,
188 long intensityLevels,
long saturationLevel,
long backgroundHalfWidth,
long lonerThreshold,
190 double *centerValue);
192void DetermineBeamSizes(
double *sigma,
double *spotRange50,
double *spotRange65,
double *spotRange80,
193 double *lineBuffer,
long i0,
long i1);
194void DetermineBeamParameters(
double **image,
long *spotROI,
long nx,
long ny,
double *S11,
double *S33,
195 double *rmsCrossProduct,
double *phi,
double *majorAxis,
double *minorAxis);
197int main(
int argc,
char **argv) {
199 long iArg, imageColumns = 0, i, ip;
200 char **imageColumn = NULL;
201 char *ixName, *iyName, *IntensityName;
203 unsigned long pipeFlags = 0, ROIFlags = 0, spotROIFlags = 0, blankOutFlags = 0;
204 int32_t intensityLevels = 256, saturationLevel = 254, backgroundHalfWidth = 3, lonerThreshold = 1, lonerPasses = 1;
208 short hotpixelFilter = 0;
209 char *inputFile = NULL, *outputFile = NULL;
210 int32_t ROI[4] = {-1, -1, -1, -1};
211 int32_t spotROISize[2] = {-1, -1};
212 char *ROIParameter[4] = {NULL, NULL, NULL, NULL};
213 int32_t blankOut[4] = {-1, -1, -1, -1};
214 char *blankOutParameter[4] = {NULL, NULL, NULL, NULL};
215 char *spotROISizeParameter[2] = {NULL, NULL};
217 long readStatus, nx, ny, outputRow, maxPages = 0;
220 unsigned long sizeLinesFlags = 0, dummyFlags = 0, backgroundFlags = 0, centerFlags = 0, majorOrderFlag;
221 int32_t sizeLines[2] = {-1, -1};
222 char *sizeLinesParameter[2] = {NULL, NULL};
223 char *centerParameter[2] = {NULL, NULL};
224 double centerValue[2];
225 char **copyParamName;
226 long copyParamNames, copyBuffer[32];
227 char *spotImageFile = NULL;
228 short columnMajorOrder = -1;
232 fprintf(stderr,
"%s%s%s", USAGE1, USAGE2, USAGE3);
236 ixName = iyName = IntensityName = NULL;
239 for (iArg = 1; iArg < argc; iArg++) {
240 if (scArg[iArg].arg_type == OPTION) {
243 switch (
match_string(scArg[iArg].list[0], option, N_OPTIONS, 0)) {
244 case SET_MAJOR_ORDER:
246 scArg[iArg].n_items--;
247 if (scArg[iArg].n_items > 0 &&
248 (!
scanItemList(&majorOrderFlag, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
249 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
250 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
251 SDDS_Bomb(
"invalid -majorOrder syntax/values");
252 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
253 columnMajorOrder = 1;
254 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
255 columnMajorOrder = 0;
257 case SET_IMAGECOLUMNS:
258 if (scArg[iArg].n_items < 2)
259 SDDS_Bomb(
"invalid -imagecolumns syntax");
261 SDDS_Bomb(
"give one and only one -imagecolumns option");
262 imageColumns = scArg[iArg].n_items - 1;
263 imageColumn =
tmalloc(
sizeof(*imageColumn) * imageColumns);
264 for (i = 0; i < imageColumns; i++)
265 imageColumn[i] = scArg[iArg].list[i + 1];
269 if (ROIFlags & OPTGIVEN)
272 scArg[iArg].n_items--;
273 if (scArg[iArg].n_items < 1 ||
274 (!
scanItemList(&ROIFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
275 "x0value",
SDDS_LONG, ROI + 0, 1, X0VALUE,
276 "x1value",
SDDS_LONG, ROI + 1, 1, X1VALUE,
277 "y0value",
SDDS_LONG, ROI + 2, 1, Y0VALUE,
278 "y1value",
SDDS_LONG, ROI + 3, 1, Y1VALUE,
279 "x0parameter",
SDDS_STRING, ROIParameter + 0, 1, X0PARAM,
280 "x1parameter",
SDDS_STRING, ROIParameter + 1, 1, X1PARAM,
281 "y0parameter",
SDDS_STRING, ROIParameter + 2, 1, Y0PARAM,
282 "y1parameter",
SDDS_STRING, ROIParameter + 3, 1, Y1PARAM,
284 ((ROIFlags & X0VALUE) && ROI[0] < 0) || ((ROIFlags & X1VALUE) && ROI[1] < 0) ||
285 ((ROIFlags & Y0VALUE) && ROI[2] < 0) || ((ROIFlags & Y1VALUE) && ROI[3] < 0) ||
286 ((ROIFlags & X0PARAM) && (!ROIParameter[0] || !strlen(ROIParameter[0]))) ||
287 ((ROIFlags & X1PARAM) && (!ROIParameter[1] || !strlen(ROIParameter[1]))) ||
288 ((ROIFlags & Y0PARAM) && (!ROIParameter[2] || !strlen(ROIParameter[2]))) ||
289 ((ROIFlags & Y1PARAM) && (!ROIParameter[3] || !strlen(ROIParameter[3])))))
293 if (blankOutFlags & OPTGIVEN)
295 blankOutFlags = OPTGIVEN;
296 scArg[iArg].n_items--;
297 if (scArg[iArg].n_items < 1 ||
298 (!
scanItemList(&blankOutFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
299 "x0value",
SDDS_LONG, blankOut + 0, 1, X0VALUE,
300 "x1value",
SDDS_LONG, blankOut + 1, 1, X1VALUE,
301 "y0value",
SDDS_LONG, blankOut + 2, 1, Y0VALUE,
302 "y1value",
SDDS_LONG, blankOut + 3, 1, Y1VALUE,
303 "x0parameter",
SDDS_STRING, blankOutParameter + 0, 1, X0PARAM,
304 "x1parameter",
SDDS_STRING, blankOutParameter + 1, 1, X1PARAM,
305 "y0parameter",
SDDS_STRING, blankOutParameter + 2, 1, Y0PARAM,
306 "y1parameter",
SDDS_STRING, blankOutParameter + 3, 1, Y1PARAM,
308 ((blankOutFlags & X0VALUE) && blankOut[0] < 0) || ((blankOutFlags & X1VALUE) && blankOut[1] < 0) ||
309 ((blankOutFlags & Y0VALUE) && blankOut[2] < 0) || ((blankOutFlags & Y1VALUE) && blankOut[3] < 0) ||
310 ((blankOutFlags & X0PARAM) && (!blankOutParameter[0] || !strlen(blankOutParameter[0]))) ||
311 ((blankOutFlags & X1PARAM) && (!blankOutParameter[1] || !strlen(blankOutParameter[1]))) ||
312 ((blankOutFlags & Y0PARAM) && (!blankOutParameter[2] || !strlen(blankOutParameter[2]))) ||
313 ((blankOutFlags & Y1PARAM) && (!blankOutParameter[3] || !strlen(blankOutParameter[3])))))
314 SDDS_Bomb(
"invalid -blankOut syntax/values");
316 case SET_SPOTROISIZE:
317 if (spotROIFlags & OPTGIVEN)
318 SDDS_Bomb(
"give -spotROIsize only once");
319 spotROIFlags = OPTGIVEN;
320 scArg[iArg].n_items--;
321 if (scArg[iArg].n_items < 1 ||
322 (!
scanItemList(&spotROIFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
323 "xvalue",
SDDS_LONG, spotROISize + 0, 1, X0VALUE,
324 "yvalue",
SDDS_LONG, spotROISize + 1, 1, Y0VALUE,
325 "xparameter",
SDDS_STRING, spotROISizeParameter + 0, 1, X0PARAM,
326 "yparameter",
SDDS_STRING, spotROISizeParameter + 1, 1, Y0PARAM,
328 ((spotROIFlags & X0VALUE) && spotROISize[0] < 0) ||
329 ((spotROIFlags & Y0VALUE) && spotROISize[1] < 0) ||
330 ((spotROIFlags & X0PARAM) && (!spotROISizeParameter[0] || !strlen(spotROISizeParameter[0]))) ||
331 ((spotROIFlags & Y0PARAM) && (!spotROISizeParameter[1] || !strlen(spotROISizeParameter[1])))))
332 SDDS_Bomb(
"invalid -spotROIsize syntax/values");
335 if (sizeLinesFlags & OPTGIVEN)
337 sizeLinesFlags = OPTGIVEN;
338 scArg[iArg].n_items--;
339 if (scArg[iArg].n_items < 1 ||
340 (!
scanItemList(&sizeLinesFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
341 "xvalue",
SDDS_LONG, sizeLines + 0, 1, X0VALUE,
342 "yvalue",
SDDS_LONG, sizeLines + 1, 1, Y0VALUE,
343 "xparameter",
SDDS_STRING, sizeLinesParameter + 0, 1, X0PARAM,
344 "yparameter",
SDDS_STRING, sizeLinesParameter + 1, 1, Y0PARAM,
346 ((sizeLinesFlags & X0VALUE) && sizeLines[0] < 0) ||
347 ((sizeLinesFlags & Y0VALUE) && sizeLines[1] < 0) ||
348 ((sizeLinesFlags & X0PARAM) && (!sizeLinesParameter[0] || !strlen(sizeLinesParameter[0]))) ||
349 ((sizeLinesFlags & Y0PARAM) && (!sizeLinesParameter[1] || !strlen(sizeLinesParameter[1])))))
350 SDDS_Bomb(
"invalid -sizeLines syntax/values");
353 scArg[iArg].n_items--;
354 despikeSettings.neighbors = 4;
355 despikeSettings.passes = 1;
356 despikeSettings.threshold = 0;
357 despikeSettings.averageOf = 2;
358 despikeSettings.flags = 0;
359 if (scArg[iArg].n_items > 0 &&
360 (!
scanItemList(&despikeSettings.flags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
361 "neighbors",
SDDS_LONG, &despikeSettings.neighbors, 1, 0,
362 "passes",
SDDS_LONG, &despikeSettings.passes, 1, 0,
363 "averageOf",
SDDS_LONG, &despikeSettings.averageOf, 1, DESPIKE_AVERAGEOF,
364 "threshold",
SDDS_DOUBLE, &despikeSettings.threshold, 1, 0,
365 "keep", -1, NULL, 0, DESPIKE_KEEP, NULL) ||
366 despikeSettings.neighbors < 2 || despikeSettings.passes < 1 ||
367 despikeSettings.averageOf < 2 || despikeSettings.threshold < 0))
368 SDDS_Bomb(
"invalid -despike syntax/values");
369 if (!(despikeSettings.flags & DESPIKE_AVERAGEOF))
370 despikeSettings.averageOf = despikeSettings.neighbors;
371 if (despikeSettings.averageOf > despikeSettings.neighbors)
372 SDDS_Bomb(
"invalid -despike syntax/values: averageOf>neighbors");
376 scArg[iArg].n_items--;
377 hotpixelSettings.passes = 1;
378 hotpixelSettings.distance = 1;
379 hotpixelSettings.fraction = -1;
380 if (scArg[iArg].n_items > 0 &&
381 (!
scanItemList(&hotpixelSettings.flags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
382 "fraction",
SDDS_DOUBLE, &hotpixelSettings.fraction, 1, 0,
383 "passes",
SDDS_LONG, &hotpixelSettings.passes, 1, 0,
384 "distance",
SDDS_LONG, &hotpixelSettings.distance, 1, 0, NULL) ||
385 hotpixelSettings.fraction <= 0 || hotpixelSettings.passes < 1 || hotpixelSettings.distance < 1))
386 SDDS_Bomb(
"invalid -hotpixelFilter syntax/values");
390 if (!
processPipeOption(scArg[iArg].list + 1, scArg[iArg].n_items - 1, &pipeFlags))
394 scArg[iArg].n_items--;
395 if (scArg[iArg].n_items < 1 ||
396 !
scanItemList(&dummyFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
397 "intensityLevels",
SDDS_LONG, &intensityLevels, 1, 0,
398 "saturationLevel",
SDDS_LONG, &saturationLevel, 1, 0, NULL) ||
399 intensityLevels <= 10 || saturationLevel <= 0)
400 SDDS_Bomb(
"invalid -levels syntax/values");
403 scArg[iArg].n_items--;
404 if (scArg[iArg].n_items < 1 ||
405 !
scanItemList(&backgroundFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
406 "halfwidth",
SDDS_LONG, &backgroundHalfWidth, 1, 0,
407 "symmetric", -1, NULL, 0, SYMMETRIC_BGREMOVAL,
408 "antihalo", -1, NULL, 0, ANTIHALO_BGREMOVAL,
409 "antiloner", -1, NULL, 0, REMOVE_LONERS,
410 "lonerthreshold",
SDDS_LONG, &lonerThreshold, 1, 0,
411 "lonerpasses",
SDDS_LONG, &lonerPasses, 1, 0, NULL) ||
412 backgroundHalfWidth < 0)
413 SDDS_Bomb(
"invalid -background syntax/values");
416 if (scArg[iArg].n_items != 1)
417 SDDS_Bomb(
"invalid -singleSpot syntax/values");
418 backgroundFlags |= SINGLE_SPOT;
421 if (scArg[iArg].n_items != 2 || !(spotImageFile = scArg[iArg].list[1]))
422 SDDS_Bomb(
"invalid -spotImage syntax/values");
424 case SET_CLIP_NEGATIVE:
425 backgroundFlags |= CLIP_NEGATIVE;
428 scArg[iArg].n_items--;
430 if (scArg[iArg].n_items < 1 ||
431 !
scanItemList(¢erFlags, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
432 "xcentroid", -1, NULL, 0, XCENTER_CENTROID,
433 "ycentroid", -1, NULL, 0, YCENTER_CENTROID,
434 "xpeak", -1, NULL, 0, XCENTER_PEAK,
435 "ypeak", -1, NULL, 0, YCENTER_PEAK,
436 "xparameter",
SDDS_STRING, centerParameter + 0, 1, XCENTER_PARAM,
437 "yparameter",
SDDS_STRING, centerParameter + 1, 1, YCENTER_PARAM, NULL) ||
438 bitsSet(centerFlags & (XCENTER_CENTROID + XCENTER_PEAK + XCENTER_PARAM)) != 1 ||
439 bitsSet(centerFlags & (YCENTER_CENTROID + YCENTER_PEAK + YCENTER_PARAM)) != 1)
443 if (scArg[iArg].n_items != 4 ||
444 !strlen(ixName = scArg[iArg].list[1]) ||
445 !strlen(iyName = scArg[iArg].list[2]) ||
446 !strlen(IntensityName = scArg[iArg].list[3]))
451 fprintf(stderr,
"unknown option %s given\n", scArg[iArg].list[0]);
458 inputFile = scArg[iArg].list[0];
459 }
else if (!outputFile) {
460 outputFile = scArg[iArg].list[0];
466 processFilenames(
"sddsspotanalysis", &inputFile, &outputFile, pipeFlags, 0, NULL);
468 if (!imageColumns && !IntensityName)
469 SDDS_Bomb(
"you must give either the -imageColumns or -xyz option");
470 if (imageColumns && IntensityName)
471 SDDS_Bomb(
"you must give either the -imageColumns or -xyz option, not both");
479 (!
SDDS_InitializeOutput(&SDDSspim, SDDS_BINARY, 0, NULL,
"sddsspotanalysis spot image", spotImageFile) ||
492 if ((imageColumns = expandColumnPairNames(&SDDSin, &imageColumn, NULL, imageColumns, NULL, 0, FIND_NUMERIC_TYPE, 0)) <= 0) {
494 SDDS_Bomb(
"No quantities selected to analyze");
498 if (!(image = calloc(ny,
sizeof(*image))))
504 if (!SetUpOutputFile(&SDDSout, outputFile, &SDDSin, ©ParamName, ©ParamNames, columnMajorOrder) ||
506 SDDS_Bomb(
"Problem setting up output file.");
509 if (readStatus > maxPages) {
511 SDDS_Bomb(
"Problem lengthening output file.");
518 if (!GetImageData(&nx, &image, imageColumn, ny, &SDDSin))
519 SDDS_Bomb(
"Problem getting image data.");
523 if (!GetXYZImageData(&nx, &ny, &image, ixName, iyName, IntensityName, &SDDSin))
524 SDDS_Bomb(
"Problem getting image data.");
528 if (!DetermineQuadLongValues(ROI, ROIFlags, ROIParameter, &SDDSin, nx, ny, 1)) {
530 SDDS_Bomb(
"Problem determining region of interest---verify that you gave sufficient information.");
532 if (blankOutFlags && !DetermineQuadLongValues(blankOut, blankOutFlags, blankOutParameter, &SDDSin, nx, ny, 0))
533 SDDS_Bomb(
"Problem determining blankout region---verify that you gave sufficient information.");
534 if (!DetermineDualLongValues(spotROISize, spotROIFlags, spotROISizeParameter, &SDDSin, 150))
535 SDDS_Bomb(
"Problem determine size of spot region of interest---verify that you gave sufficient information.");
536 if (!DetermineDualLongValues(sizeLines, sizeLinesFlags, sizeLinesParameter, &SDDSin, 3))
537 SDDS_Bomb(
"Problem determine size of number of lines to use for spot size computation---verify that you gave sufficient information.");
538 centerValue[0] = centerValue[1] = -1;
540 SDDS_Bomb(
"Problem getting center parameter value for x.");
542 SDDS_Bomb(
"Problem getting center parameter value for y.");
544 BlankOutImageData(image, nx, ny, blankOut);
545 if (!AnalyzeImageData(image, nx, ny, ROI, spotROISize, sizeLines,
546 despike ? &despikeSettings : NULL, hotpixelFilter ? &hotpixelSettings : NULL, intensityLevels,
547 saturationLevel, backgroundHalfWidth, lonerThreshold, lonerPasses, backgroundFlags | centerFlags,
548 &analysisResults, spotImageFile ? &SDDSspim : NULL, centerValue))
550 for (ip = 0; ip < copyParamNames; ip++) {
552 SDDS_Bomb(
"Problem reading parameter data from input file.");
553 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, outputRow, copyParamName[ip], copyBuffer, NULL)) {
554 SDDS_Bomb(
"Problem copying parameter data from input file.");
557 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, outputRow++,
558 "ImageIndex", readStatus - 1,
559 "xROILower", analysisResults.ROI[0],
560 "xROIUpper", analysisResults.ROI[1],
561 "yROILower", analysisResults.ROI[2],
562 "yROIUpper", analysisResults.ROI[3],
563 "xSpotROILower", analysisResults.spotROI[0],
564 "xSpotROIUpper", analysisResults.spotROI[1],
565 "ySpotROILower", analysisResults.spotROI[2],
566 "ySpotROIUpper", analysisResults.spotROI[3],
567 "xSpotCenter", analysisResults.spotCenter[0],
568 "ySpotCenter", analysisResults.spotCenter[1],
569 "xSpotCentroid", analysisResults.spotCentroid[0],
570 "ySpotCentroid", analysisResults.spotCentroid[1],
571 "xSpotSigma", analysisResults.spotSigma[0],
572 "xSpotRange50", analysisResults.spotRange50[0],
573 "xSpotRange65", analysisResults.spotRange65[0],
574 "xSpotRange80", analysisResults.spotRange80[0],
575 "ySpotSigma", analysisResults.spotSigma[1],
576 "ySpotRange50", analysisResults.spotRange50[1],
577 "ySpotRange65", analysisResults.spotRange65[1],
578 "ySpotRange80", analysisResults.spotRange80[1],
579 "BackgroundLevel", analysisResults.backgroundLevel,
580 "BackgroundKilledPositive", analysisResults.backgroundKilledPositive,
581 "BackgroundKilledNegative", analysisResults.backgroundKilledNegative,
582 "IntegratedSpotIntensity", analysisResults.integratedSpotIntensity,
583 "PeakSpotIntensity", analysisResults.peakSpotIntensity,
584 "SaturationCount", analysisResults.saturationCount,
585 "phi", analysisResults.phi,
586 "rmsCrossProduct", analysisResults.rmsCrossProduct,
587 "majorAxis", analysisResults.majorAxis,
588 "minorAxis", analysisResults.minorAxis,
589 "S11", analysisResults.S11,
590 "S33", analysisResults.S33,
591 "S13", analysisResults.rmsCrossProduct, NULL)) {
600 for (i = 0; i < ny; i++)
603 for (i = 0; i < ny; i++)
604 free(imageColumn[i]);
607 for (i = 0; i < copyParamNames; i++)
608 free(copyParamName[i]);
615 long *copyParamNames,
short columnMajorOrder) {
658 if (columnMajorOrder != -1)
659 SDDSout->layout.data_mode.column_major = columnMajorOrder;
661 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
664 *copyParamName = NULL;
667 if (!(*copyParamName = calloc(
sizeof(**copyParamName), paramNames)))
669 for (ip = 0; ip < paramNames; ip++) {
679 (*copyParamName)[*copyParamNames] = paramName[ip];
692long DetermineQuadLongValues(int32_t *ROI,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long nx,
long ny,
long isROI) {
695 double defaultROI[4];
697 defaultROI[0] = defaultROI[2] = 0;
698 defaultROI[1] = nx - 1;
699 defaultROI[3] = ny - 1;
701 defaultROI[0] = defaultROI[2] = defaultROI[1] = defaultROI[3] = -1;
702 for (i = 0; i < 4; i++) {
703 if (flags & (X0VALUE << i))
705 if (flags & (X0PARAM << i)) {
710 ROI[i] = value + 0.5;
712 ROI[i] = defaultROI[i];
714 if (ROI[0] < 0 || ROI[2] < 0) {
718 if (ROI[1] > nx - 1 || ROI[3] > ny - 1) {
722 if (ROI[0] >= ROI[1]) {
726 if (ROI[2] >= ROI[3]) {
733long DetermineDualLongValues(int32_t *returnValue,
unsigned long flags,
char **parameter,
SDDS_DATASET *SDDSin,
long defaultValue) {
737 for (i = 0; i < 2; i++) {
738 if (flags & (X0VALUE << (2 * i)))
740 if (flags & (X0PARAM << (2 * i))) {
745 returnValue[i] = (int32_t)value;
747 returnValue[i] = defaultValue;
749 if (returnValue[0] <= 0 || returnValue[1] <= 0) {
756long GetImageData(
long *nx,
double ***image,
char **imageColumn,
long ny,
SDDS_DATASET *SDDSin) {
763 for (i = 0; i < ny; i++) {
769 SDDS_Bomb(
"Unable to get data from columns");
772 *nx = SDDS_RowCount(SDDSin);
776long GetXYZImageData(
long *nx,
long *ny,
double ***image,
char *ixName,
char *iyName,
char *intensityName,
SDDS_DATASET *SDDSin) {
777 int32_t *ixData, *iyData;
778 double *intensityData;
779 long ixMin, iyMin, ixMax, iyMax, i, ix, iy, nRows;
780 char *ixIndexCheck, *iyIndexCheck;
782 if ((nRows = SDDS_RowCount(SDDSin)) <= 0 ||
788 ixMax = iyMax = -(ixMin = iyMin = LONG_MAX);
790 for (i = 0; i < nRows; i++) {
791 if (ixMax < ixData[i])
793 if (ixMin > ixData[i])
795 if (iyMax < iyData[i])
797 if (iyMin > iyData[i])
805 ixIndexCheck = calloc((*nx = ixMax - ixMin + 1),
sizeof(*ixIndexCheck));
806 iyIndexCheck = calloc((*ny = iyMax - iyMin + 1),
sizeof(*iyIndexCheck));
808 *image = calloc(*ny,
sizeof(**image));
809 for (iy = 0; iy < *ny; iy++)
810 (*image)[iy] = calloc(*nx,
sizeof(***image));
812 for (i = 0; i < nRows; i++) {
813 ix = ixData[i] - ixMin;
814 iy = iyData[i] - iyMin;
815 ixIndexCheck[ix] = 1;
816 iyIndexCheck[iy] = 1;
817 (*image)[iy][ix] = intensityData[i];
820 for (i = 0; i <= (ixMax - ixMin); i++) {
821 if (!ixIndexCheck[i]) {
822 fprintf(stderr,
"Error: image file is missing some x index values\n");
824 for (
long y = 0; y < *ny; y++) {
836 for (i = 0; i <= (iyMax - iyMin); i++) {
837 if (!iyIndexCheck[i]) {
838 fprintf(stderr,
"Error: image file is missing some y index values\n");
840 for (
long y = 0; y < *ny; y++) {
862long AnalyzeImageData(
double **image,
long nx,
long ny, int32_t *ROI, int32_t *spotROISize, int32_t *sizeLines,
864 long intensityLevels,
long saturationLevel,
long backgroundHalfWidth,
long lonerThreshold,
865 long lonerPasses,
unsigned long flags,
IMAGE_ANALYSIS *analysisResults,
867 long ix, iy, iy0, iy1, ix0, ix1, nxROI, nyROI;
868 double maxValue, minValue, background, value, sum1, sum2;
869 long ixCenter, iyCenter;
870 int64_t ixMax, ixMin;
872 double *intensityHistogram, *lineBuffer = NULL, *x = NULL, *y = NULL;
892 if (ROI[0] >= 0 && ROI[1] >= 0 && ROI[0] < ROI[1]) {
901 nxROI = ix1 - ix0 + 1;
903 if (ROI[2] >= 0 && ROI[3] >= 0 && ROI[2] < ROI[3]) {
912 nyROI = iy1 - iy0 + 1;
914 if ((nyROI) < spotROISize[1] || (nxROI) < spotROISize[0])
915 SDDS_Bomb(
"spot ROI is larger than ROI");
919 if (!(lineBuffer =
SDDS_Malloc(
sizeof(*lineBuffer) * (nx > ny ? nx : ny))))
923 ixCenter = iyCenter = -1;
925 for (ix = ix0; ix <= ix1; ix++) {
926 for (iy = iy0; iy <= iy1; iy++) {
927 if ((flags & CLIP_NEGATIVE) && image[iy][ix] < 0)
929 if (image[iy][ix] < 0 || image[iy][ix] >= intensityLevels)
930 SDDS_Bomb(
"image intensity outside intensity level range");
934 if (despikeSettings && (despikeSettings->flags & DESPIKE_KEEP)) {
936 for (ix = ix0; ix <= ix1; ix++) {
937 for (iy = iy0; iy <= iy1; iy++)
938 lineBuffer[iy - iy0] = image[iy][ix];
939 despikeData(lineBuffer, nyROI, despikeSettings->neighbors, despikeSettings->passes, despikeSettings->averageOf,
940 despikeSettings->threshold, 0);
941 for (iy = iy0; iy <= iy1; iy++)
942 image[iy][ix] = lineBuffer[iy - iy0];
947 for (iy = iy0; iy <= iy1; iy++) {
948 if (despikeSettings) {
949 memcpy(lineBuffer, image[iy] + ix0, nxROI *
sizeof(*lineBuffer));
950 despikeData(lineBuffer, nxROI, despikeSettings->neighbors, despikeSettings->passes, despikeSettings->averageOf,
951 despikeSettings->threshold, 0);
952 if (despikeSettings->flags & DESPIKE_KEEP)
953 memcpy(image[iy] + ix0, lineBuffer, nxROI *
sizeof(*lineBuffer));
955 lineBuffer = image[iy] + ix0;
957 if (lineBuffer[ixMax] > maxValue) {
958 maxValue = lineBuffer[ixMax];
959 ixCenter = ixMax + ix0;
962 if (lineBuffer[ixMin] < minValue)
963 minValue = lineBuffer[ixMin];
965 if (despikeSettings) {
969 if (flags & XCENTER_PARAM)
970 ixCenter = centerValue[0];
972 centerValue[0] = ixCenter;
973 if (flags & YCENTER_PARAM)
974 iyCenter = centerValue[1];
976 centerValue[1] = iyCenter;
977 if (ixCenter == -1 || iyCenter == -1)
981 if (!(intensityHistogram = calloc(intensityLevels,
sizeof(*intensityHistogram))))
983 for (iy = iy0; iy <= iy1; iy++)
984 make_histogram(intensityHistogram, intensityLevels, -0.5, intensityLevels + 0.5, image[iy] + ix0, nxROI, iy == iy0);
985 index_min_max(&ixMin, &ixMax, intensityHistogram, intensityLevels);
987 for (i = ixMax - backgroundHalfWidth; i <= ixMax + backgroundHalfWidth; i++) {
988 if (i < 0 || i >= intensityLevels)
990 sum1 += intensityHistogram[i];
991 sum2 += intensityHistogram[i] * i;
994 background = sum2 / sum1;
999 free(intensityHistogram);
1001 if (hotpixelSettings) {
1002 long min, max, pass;
1008 pass = hotpixelSettings->passes;
1010 max = -(min = LONG_MAX);
1011 for (iy = iy0; iy <= iy1; iy++) {
1012 for (ix = ix0; ix <= ix1; ix++) {
1013 if (image[iy][ix] > max)
1014 max = image[iy][ix];
1015 if (image[iy][ix] < min)
1016 min = image[iy][ix];
1020 SDDS_Bomb(
"Can't apply hotpixel filter (min=max). Are data non-integer?");
1021 for (iy = iy0; iy <= iy1; iy++)
1022 for (ix = ix0; ix <= ix1; ix++)
1023 if ((image[iy][ix] - min) > (max - min) * hotpixelSettings->fraction)
1024 replaceWithNearNeighbors(image, iy0, iy1, ix0, ix1, iy, ix, hotpixelSettings->distance);
1029 if (flags & XCENTER_CENTROID) {
1031 for (ix = ix0; ix <= ix1; ix++)
1032 for (iy = iy0; iy <= iy1; iy++) {
1033 sum += image[iy][ix];
1034 mean += image[iy][ix] * ix;
1037 spotROI[0] = mean - spotROISize[0] / 2;
1039 spotROI[0] = ixCenter - spotROISize[0] / 2;
1041 spotROI[1] = spotROI[0] + spotROISize[0] - 1;
1042 if (spotROI[0] < ix0) {
1044 spotROI[1] = ix0 + spotROISize[0] - 1;
1045 }
else if (spotROI[1] > ix1) {
1047 spotROI[0] = ix1 - spotROISize[0] + 1;
1049 if (spotROI[0] < ix0 || spotROI[1] > ix1)
1050 SDDS_Bomb(
"spot ROI is larger than ROI for x");
1052 if (flags & XCENTER_CENTROID) {
1054 for (ix = ix0; ix <= ix1; ix++)
1055 for (iy = iy0; iy <= iy1; iy++) {
1056 sum += image[iy][ix];
1057 mean += image[iy][ix] * iy;
1060 spotROI[2] = mean - spotROISize[1] / 2;
1062 spotROI[2] = iyCenter - spotROISize[1] / 2;
1065 spotROI[3] = spotROI[2] + spotROISize[1] - 1;
1066 if (spotROI[2] < iy0) {
1068 spotROI[3] = iy0 + spotROISize[1] - 1;
1069 }
else if (spotROI[3] > iy1) {
1071 spotROI[2] = iy1 - spotROISize[1] + 1;
1073 if (spotROI[2] < iy0 || spotROI[3] > iy1)
1074 SDDS_Bomb(
"spot ROI is larger than ROI for y");
1077 analysisResults->saturationCount = 0;
1078 analysisResults->integratedSpotIntensity = 0;
1079 analysisResults->backgroundKilledNegative = 0;
1080 analysisResults->backgroundKilledPositive = 0;
1081 saturationLevel -= (long)background;
1082 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1083 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1084 if ((value = image[iy][ix] - background) <= 0) {
1085 analysisResults->backgroundKilledNegative += 1;
1088 image[iy][ix] = value;
1091 if (flags & SYMMETRIC_BGREMOVAL) {
1092 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1093 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1094 long ox, oy, goodPixels;
1095 long ox0, ox1, oy0, oy1;
1096 if (image[iy][ix] > 0 && image[iy][ix] <= backgroundHalfWidth) {
1100 ox0 = (ix == spotROI[0] ? 0 : -1);
1101 ox1 = (ix == spotROI[1] ? 0 : 1);
1102 oy0 = (iy == spotROI[2] ? 0 : -1);
1103 oy1 = (iy == spotROI[3] ? 0 : 1);
1106 goodPixels = (ox1 - ox0 + 1) * (oy1 - oy0 + 1);
1107 for (ox = ox0; ox <= ox1; ox++) {
1108 for (oy = oy0; oy <= oy1; oy++) {
1109 if (image[iy + oy][ix + ox] <= backgroundHalfWidth)
1113 if (goodPixels <= 1) {
1114 analysisResults->backgroundKilledPositive += 1;
1121 if (flags & REMOVE_LONERS) {
1122 while (lonerPasses-- > 0) {
1123 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1124 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1125 long ox, oy, company;
1126 long ox0, ox1, oy0, oy1;
1127 if (image[iy][ix] > 0) {
1130 ox0 = (ix == spotROI[0] ? 0 : -1);
1131 ox1 = (ix == spotROI[1] ? 0 : 1);
1132 oy0 = (iy == spotROI[2] ? 0 : -1);
1133 oy1 = (iy == spotROI[3] ? 0 : 1);
1136 company = (ox1 - ox0 + 1) * (oy1 - oy0 + 1);
1137 for (ox = ox0; ox <= ox1; ox++) {
1138 for (oy = oy0; oy <= oy1; oy++) {
1139 if (image[iy + oy][ix + ox] == 0)
1143 if (company <= lonerThreshold) {
1144 analysisResults->backgroundKilledPositive += 1;
1152 if (flags & ANTIHALO_BGREMOVAL) {
1154 for (tryCount = 0; tryCount < 2; tryCount++) {
1155 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1156 for (iy = spotROI[2]; iy < spotROI[3]; iy++) {
1157 if (image[iy][ix] > backgroundHalfWidth || image[iy + 1][ix] > backgroundHalfWidth)
1159 if (image[iy][ix]) {
1161 analysisResults->backgroundKilledPositive += 1;
1164 if (iy != spotROI[3])
1165 for (iy = spotROI[3]; iy > spotROI[2]; iy--) {
1166 if (image[iy][ix] > backgroundHalfWidth || image[iy - 1][ix] > backgroundHalfWidth)
1168 if (image[iy][ix]) {
1170 analysisResults->backgroundKilledPositive += 1;
1174 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1175 for (ix = spotROI[0]; ix < spotROI[1]; ix++) {
1176 if (image[iy][ix] > backgroundHalfWidth || image[iy][ix + 1] > backgroundHalfWidth)
1178 if (image[iy][ix]) {
1180 analysisResults->backgroundKilledPositive += 1;
1183 if (ix != spotROI[1])
1184 for (ix = spotROI[1]; ix > spotROI[0]; ix--) {
1185 if (image[iy][ix] > backgroundHalfWidth || image[iy][ix - 1] > backgroundHalfWidth)
1187 if (image[iy][ix]) {
1189 analysisResults->backgroundKilledPositive += 1;
1195 if (flags & SINGLE_SPOT) {
1196 short **connected, changed;
1198 long ix_max = 0, iy_max = 0;
1200 connected =
tmalloc(
sizeof(*connected) * nx);
1201 for (ix = 0; ix < nx; ix++)
1202 connected[ix] =
tmalloc(
sizeof(**connected) * ny);
1204 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1205 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1206 connected[ix][iy] = 0;
1207 if (image[iy][ix] > maxVal) {
1210 maxVal = image[iy][ix];
1213 connected[ix_max][iy_max] = 1;
1217 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1218 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1219 if (!image[iy][ix] || connected[ix][iy])
1221 if (ix > spotROI[0] && connected[ix - 1][iy]) {
1222 changed += (connected[ix][iy] = 1);
1225 if (ix < spotROI[1] && connected[ix + 1][iy]) {
1226 changed += (connected[ix][iy] = 1);
1229 if (iy > spotROI[2] && connected[ix][iy - 1]) {
1230 changed += (connected[ix][iy] = 1);
1233 if (iy < spotROI[3] && connected[ix][iy + 1]) {
1234 changed += (connected[ix][iy] = 1);
1238 for (ix = spotROI[1]; ix >= spotROI[0]; ix--)
1239 for (iy = spotROI[3]; iy >= spotROI[2]; iy--) {
1240 if (!image[iy][ix] || connected[ix][iy])
1242 if (ix > spotROI[0] && connected[ix - 1][iy]) {
1243 changed += (connected[ix][iy] = 1);
1246 if (ix < spotROI[1] && connected[ix + 1][iy]) {
1247 changed += (connected[ix][iy] = 1);
1250 if (iy > spotROI[2] && connected[ix][iy - 1]) {
1251 changed += (connected[ix][iy] = 1);
1254 if (iy < spotROI[3] && connected[ix][iy + 1]) {
1255 changed += (connected[ix][iy] = 1);
1261 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1262 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1263 if (!connected[ix][iy])
1267 for (ix = 0; ix < nx; ix++) {
1268 free(connected[ix]);
1274 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1275 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1276 if (image[iy][ix] > saturationLevel)
1277 analysisResults->saturationCount += 1;
1280 analysisResults->spotCentroid[0] = analysisResults->spotCentroid[1] = 0;
1281 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1282 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1283 analysisResults->integratedSpotIntensity += image[iy][ix];
1284 analysisResults->spotCentroid[0] += image[iy][ix] * ix;
1285 analysisResults->spotCentroid[1] += image[iy][ix] * iy;
1287 if (analysisResults->integratedSpotIntensity)
1288 for (i = 0; i < 2; i++)
1289 analysisResults->spotCentroid[i] /= analysisResults->integratedSpotIntensity;
1292 if (!(lineBuffer = calloc(ny,
sizeof(*lineBuffer))))
1294 if (!(x = calloc(ny,
sizeof(*x))))
1296 if (!(y = calloc(ny,
sizeof(*y))))
1298 for (ix = ixCenter - sizeLines[0] / 2; ix <= ixCenter + sizeLines[0] / 2; ix++) {
1299 if (ix < ix0 || ix > ix1)
1301 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1302 lineBuffer[iy] += image[iy][ix];
1304 for (iy = spotROI[2]; iy <= spotROI[3]; iy++)
1305 y[iy] = lineBuffer[iy];
1307 DetermineBeamSizes(&analysisResults->spotSigma[1], &analysisResults->spotRange50[1], &analysisResults->spotRange65[1],
1308 &analysisResults->spotRange80[1], lineBuffer, spotROI[2], spotROI[3]);
1311 if (!(lineBuffer = calloc(nx,
sizeof(*lineBuffer))))
1313 for (iy = iyCenter - sizeLines[1] / 2; iy <= iyCenter + sizeLines[1] / 2; iy++) {
1314 if (iy < iy0 || iy > iy1)
1316 for (ix = spotROI[0]; ix <= spotROI[1]; ix++)
1317 lineBuffer[ix] += image[iy][ix];
1319 DetermineBeamSizes(&analysisResults->spotSigma[0], &analysisResults->spotRange50[0], &analysisResults->spotRange65[0],
1320 &analysisResults->spotRange80[0], lineBuffer, spotROI[0], spotROI[1]);
1322 DetermineBeamParameters(image, spotROI, nx, ny, &analysisResults->S11, &analysisResults->S33, &analysisResults->rmsCrossProduct,
1323 &analysisResults->phi, &analysisResults->majorAxis, &analysisResults->minorAxis);
1325 analysisResults->peakSpotIntensity = maxValue - background;
1326 analysisResults->spotCenter[0] = ixCenter;
1327 analysisResults->spotCenter[1] = iyCenter;
1328 analysisResults->backgroundLevel = background;
1329 analysisResults->ROI[0] = ix0;
1330 analysisResults->ROI[1] = ix1;
1331 analysisResults->ROI[2] = iy0;
1332 analysisResults->ROI[3] = iy1;
1333 for (i = 0; i < 4; i++)
1334 analysisResults->spotROI[i] = spotROI[i];
1342 if (!
SDDS_StartPage(SDDSspim, (spotROI[1] - spotROI[0] + 1) * (spotROI[3] - spotROI[2] + 1)))
1343 SDDS_Bomb(
"Problem starting page for spot image output file.");
1344 if (!
SDDS_SetParameters(SDDSspim, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
"nx", (
short)(spotROI[1] - spotROI[0] + 1),
1345 "ny", (
short)(spotROI[3] - spotROI[2] + 1), NULL))
1346 SDDS_Bomb(
"Problem setting parameter values for spot image output file.");
1348 for (iy = spotROI[2]; iy <= spotROI[3]; iy++) {
1349 for (ix = spotROI[0]; ix <= spotROI[1]; ix++) {
1350 if (!
SDDS_SetRowValues(SDDSspim, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, i_row++,
"ix", (
short)ix,
1351 "iy", (
short)iy,
"Image", image[iy][ix], NULL)) {
1352 SDDS_Bomb(
"Problem setting row values for spot image output file.");
1357 SDDS_Bomb(
"Problem writing page for spot image output file.");
1363void DetermineBeamSizes(
double *sigma,
double *Range50,
double *Range65,
double *Range80,
double *lineBuffer,
long i0,
long i1) {
1364 double centroid, sum;
1366 double pLevel[6] = {.10, .175, .25, .75, .825, .90};
1370 *sigma = *Range80 = *Range65 = *Range50 = 0;
1371 for (i = i0; i <= i1; i++) {
1372 sum += lineBuffer[i];
1373 centroid += lineBuffer[i] * i;
1376 centroid = centroid / sum;
1377 for (i = i0; i <= i1; i++)
1378 *sigma += lineBuffer[i] * sqr(i - centroid);
1379 *sigma = sqrt(*sigma / sum);
1382 for (i = i0 + 1; i <= i1; i++)
1383 lineBuffer[i] += lineBuffer[i - 1];
1384 if (lineBuffer[i1]) {
1385 for (i = i0; i <= i1; i++)
1386 lineBuffer[i] /= lineBuffer[i1];
1388 for (j = 0; j < 6; j++) {
1390 while (i <= i1 && lineBuffer[i] < pLevel[j])
1394 }
else if (lineBuffer[i] == lineBuffer[i - 1])
1395 pValue[j] = i - 0.5;
1397 pValue[j] = i - (lineBuffer[i] - pLevel[j]) / (lineBuffer[i] - lineBuffer[i - 1]);
1399 *Range80 = pValue[5] - pValue[0];
1400 *Range65 = pValue[4] - pValue[1];
1401 *Range50 = pValue[3] - pValue[2];
1406void BlankOutImageData(
double **image,
long nx,
long ny, int32_t *region) {
1407 long ix, iy, count = 0;
1408 for (ix = region[0]; ix <= region[1]; ix++)
1409 for (iy = region[2]; iy <= region[3]; iy++, count++)
1413void DetermineBeamParameters(
double **image,
long *spotROI,
long nx,
long ny,
double *S11,
double *S33,
1414 double *rmsCrossProduct,
double *phi,
double *majorAxis,
double *minorAxis) {
1416 long x1, x2, y1, y2;
1417 double imageArea = 0, x2Ave = 0, y2Ave = 0, xyAve = 0, dominator = 0, xcentroid = 0, ycentroid = 0;
1425 for (i = y1; i <= y2; i++)
1426 for (j = x1; j <= x2; j++) {
1427 imageArea += image[i][j];
1428 xcentroid += image[i][j] * j;
1429 ycentroid += image[i][j] * i;
1431 if (imageArea == 0) {
1432 *rmsCrossProduct = *majorAxis = *minorAxis = DBL_MAX;
1434 xcentroid = xcentroid / imageArea;
1435 ycentroid = ycentroid / imageArea;
1436 for (i = y1; i <= y2; i++)
1437 for (j = x1; j <= x2; j++) {
1438 x2Ave += sqr(j - xcentroid) * image[i][j];
1439 y2Ave += sqr(i - ycentroid) * image[i][j];
1440 xyAve += (i - ycentroid) * (j - xcentroid) * image[i][j];
1442 x2Ave = x2Ave / imageArea;
1443 y2Ave = y2Ave / imageArea;
1444 xyAve = xyAve / imageArea;
1445 dominator = x2Ave * y2Ave - xyAve * xyAve;
1448 *rmsCrossProduct = xyAve;
1449 *phi = 0.5 * atan2(2 * xyAve, x2Ave - y2Ave) / PI * 180;
1450 if ((x2Ave + y2Ave - sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))) != 0) {
1451 *majorAxis = sqrt(2 * dominator / (x2Ave + y2Ave - sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))));
1453 *majorAxis = DBL_MAX;
1455 if ((x2Ave + y2Ave + sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))) != 0) {
1456 *minorAxis = sqrt(2 * dominator / (x2Ave + y2Ave + sqrt(sqr(x2Ave - y2Ave) + 4 * sqr(xyAve))));
1458 *minorAxis = DBL_MAX;
1463void replaceWithNearNeighbors(
double **image,
long iy0,
long iy1,
long ix0,
long ix1,
long iyc,
long ixc,
long distance) {
1467 if ((iyc - distance) > iy0)
1468 iy0 = iyc - distance;
1469 if ((iyc + distance) < iy1)
1470 iy1 = iyc + distance;
1472 if ((ixc - distance) > ix0)
1473 ix0 = ixc - distance;
1474 if ((ixc + distance) < ix1)
1475 ix1 = ixc + distance;
1479 for (iy = iy0; iy <= iy1; iy++)
1480 for (ix = ix0; ix <= ix1; ix++) {
1481 if (ix == ixc && iy == iyc)
1483 sum += image[iy][ix];
1488 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.
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.