59 SET_DIFFERENCECOLUMNS,
65char *option[N_OPTIONS] = {
84 "Usage: sddsfdfilter [<inputfile>] [<outputfile>]\n"
85 " [-pipe=[input][,output]]\n"
86 " [-columns=<indep-variable>[,<depen-quantity>[,...]]]\n"
87 " [-exclude=<depen-quantity>[,...]]\n"
88 " [-clipFrequencies=[high=<number>][,low=<number>]]\n"
89 " [-threshold=level=<value>[,fractional][,start=<freq>][,end=<freq>]]\n"
90 " [-highpass=start=<freq>,end=<freq>]\n"
91 " [-lowpass=start=<freq>,end=<freq>]\n"
92 " [-notch=center=<center>,flatWidth=<value>,fullWidth=<value>]\n"
93 " [-bandpass=center=<center>,flatWidth=<value>,fullWidth=<value>]\n"
94 " [-filterFile=filename=<filename>,frequency=<columnName>{,real=<cName>,imaginary=<cName>|magnitude=<cName>}]\n"
97 " [-differenceColumns]\n"
98 " [-majorOrder=row|column]\n\n"
99 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
101#define FILT_START_GIVEN 0x00000001U
102#define FILT_END_GIVEN 0x00000002U
103#define FILT_THRES_GIVEN 0x00000004U
104#define FILT_CENTER_GIVEN 0x00000008U
105#define FILT_FULLWIDTH_GIVEN 0x00000010U
106#define FILT_FREQNAME_GIVEN 0x00000020U
107#define FILT_REALNAME_GIVEN 0x00000040U
108#define FILT_IMAGNAME_GIVEN 0x00000080U
109#define FILT_MAGNAME_GIVEN 0x00000100U
110#define FILT_FRACTHRES_GIVEN 0x00000200U
111#define FILT_LEVEL_GIVEN 0x00000400U
112#define FILT_FILENAME_GIVEN 0x00000800U
113#define FILT_HIGH_GIVEN 0x00001000U
114#define FILT_LOW_GIVEN 0x00002000U
115#define FILT_FLATWIDTH_GIVEN 0x00004000U
118 double level, start, end;
128 double center, fullwidth, flatwidth;
133 char *file, *freqName, *realName, *imagName, *magName;
134 double *freqData, *realData, *imagData, *magData;
154#define FL_NEWCOLUMNS 0x00001UL
155#define FL_DIFCOLUMNS 0x00002UL
157long applyFilters(
double *outputData,
double *inputData,
double *timeData, int64_t rows,
FILTER_STAGE *filterStage,
long filterStages);
158long applyFilterStage(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
FILTER_STAGE *filterStage);
159void addClipFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
CLIP_FILTER *filter);
160void addThresholdFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
THRESHOLD_FILTER *filter);
161void addHighPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
HILO_FILTER *filter);
162void addLowPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
HILO_FILTER *filter);
163void addNotchFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
NHBP_FILTER *filter);
164void addBandPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
NHBP_FILTER *filter);
165void addFileFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
FILE_FILTER *filter);
166int64_t computeIndex(
double value,
double dfrequency, int64_t frequencies);
167void addFilter(
FILTER_STAGE *filterStage,
long optionCode, SCANNED_ARG *scanned);
169int main(
int argc,
char **argv) {
171 char **outputColumn, **difColumn;
172 char *indepColumn, **depenColumn, **exclude;
173 long depenColumns, excludes;
174 char *input, *output;
175 long i, readCode, optionCode;
177 unsigned long flags, pipeFlags, majorOrderFlag;
178 SCANNED_ARG *scanned;
180 double *timeData, *inputData, *outputData;
182 long filterStages, totalFilters;
183 short columnMajorOrder = -1;
186 argc =
scanargs(&scanned, argc, argv);
187 if (argc < 3 || argc > (3 + N_OPTIONS))
190 output = input = NULL;
191 flags = pipeFlags = 0;
193 depenColumn = exclude = NULL;
194 depenColumns = excludes = 0;
195 if (!(filterStage = (
FILTER_STAGE *)calloc(1,
sizeof(*filterStage))))
198 filterStage->filter = NULL;
199 filterStage->filters = 0;
203 for (iArg = 1; iArg < argc; iArg++) {
204 if (scanned[iArg].arg_type == OPTION) {
206 switch (optionCode =
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
207 case SET_MAJOR_ORDER:
209 scanned[iArg].n_items--;
210 if (scanned[iArg].n_items > 0 && (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
211 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
212 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
213 SDDS_Bomb(
"invalid -majorOrder syntax/values");
214 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
215 columnMajorOrder = 1;
216 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
217 columnMajorOrder = 0;
220 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
225 SDDS_Bomb(
"only one -columns option may be given");
226 if (scanned[iArg].n_items < 2)
228 indepColumn = scanned[iArg].list[1];
229 if (scanned[iArg].n_items >= 2) {
230 depenColumn =
tmalloc(
sizeof(*depenColumn) * (depenColumns = scanned[iArg].n_items - 2));
231 for (i = 0; i < depenColumns; i++)
232 depenColumn[i] = scanned[iArg].list[i + 2];
242 addFilter(filterStage + filterStages - 1, optionCode, scanned + iArg);
246 if (filterStages == 0)
247 SDDS_Bomb(
"-cascade option precedes all filter definitions");
248 if (!(filterStage =
SDDS_Realloc(filterStage, (filterStages + 1) *
sizeof(*filterStage))))
250 filterStage[filterStages].filter = NULL;
251 filterStage[filterStages].filters = 0;
255 flags |= FL_NEWCOLUMNS;
257 case SET_DIFFERENCECOLUMNS:
258 flags |= FL_DIFCOLUMNS;
261 if (scanned[iArg].n_items < 2)
263 moveToStringArray(&exclude, &excludes, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
266 fprintf(stderr,
"error: unknown/ambiguous option: %s (%s)\n", scanned[iArg].list[0], argv[0]);
272 input = scanned[iArg].list[0];
274 output = scanned[iArg].list[0];
283 fputs(
"warning: no filters specified (sddsfdfilter)\n", stderr);
286 SDDS_Bomb(
"supply the independent column name with the -columns option");
294 excludes = appendToStringArray(&exclude, excludes, indepColumn);
296 depenColumns = appendToStringArray(&depenColumn, depenColumns,
"*");
298 if ((depenColumns = expandColumnPairNames(&SDDSin, &depenColumn, NULL, depenColumns, exclude, excludes, FIND_NUMERIC_TYPE, 0)) <= 0) {
300 SDDS_Bomb(
"No quantities selected to filter");
306 if (columnMajorOrder != -1)
307 SDDSout.layout.data_mode.column_major = columnMajorOrder;
309 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
311 if (flags & FL_NEWCOLUMNS) {
312 outputColumn =
tmalloc(
sizeof(*outputColumn) * depenColumns);
313 for (i = 0; i < depenColumns; i++) {
314 outputColumn[i] =
tmalloc(
sizeof(**outputColumn) * (strlen(depenColumn[i]) + 1 + strlen(
"Filtered")));
315 sprintf(outputColumn[i],
"%sFiltered", depenColumn[i]);
320 outputColumn = depenColumn;
323 if (flags & FL_DIFCOLUMNS) {
324 difColumn =
tmalloc(
sizeof(*difColumn) * depenColumns);
325 for (i = 0; i < depenColumns; i++) {
326 difColumn[i] =
tmalloc(
sizeof(**difColumn) * (strlen(depenColumn[i]) + 1 + strlen(
"Difference")));
327 sprintf(difColumn[i],
"%sDifference", depenColumn[i]);
346 if (!(outputData =
SDDS_Realloc(outputData,
sizeof(*outputData) * rows)))
348 for (i = 0; i < depenColumns; i++) {
351 if (!applyFilters(outputData, inputData, timeData, rows, filterStage, filterStages))
355 if (flags & FL_DIFCOLUMNS) {
357 for (j = 0; j < rows; j++)
358 outputData[j] = inputData[j] - outputData[j];
371 for (i = 0; i < depenColumns; i++) {
372 free(depenColumn[i]);
373 if (flags & FL_NEWCOLUMNS)
374 free(outputColumn[i]);
375 if (flags & FL_DIFCOLUMNS)
378 for (i = 0; i < excludes; i++)
382 if (flags & FL_NEWCOLUMNS)
385 if (flags & FL_DIFCOLUMNS)
388 for (i = 0; i < filterStages; i++) {
390 for (j = 0; j < filterStage[i].filters; j++) {
391 switch (filterStage[i].filter[j].filterType) {
393 free(((
FILE_FILTER *)(filterStage[i].filter[j].filter))->freqData);
394 free(((
FILE_FILTER *)(filterStage[i].filter[j].filter))->magData);
395 free(((
FILE_FILTER *)(filterStage[i].filter[j].filter))->imagData);
396 free(((
FILE_FILTER *)(filterStage[i].filter[j].filter))->realData);
410long applyFilters(
double *outputData,
double *inputData,
double *timeData, int64_t rows,
FILTER_STAGE *filterStage,
long filterStages) {
412 int64_t frequencies, row;
413 double *realimagInput, *realimagOutput;
414 double length, dfrequency, factor;
415 realimagOutput = NULL;
416 if (!(realimagInput = (
double *)malloc(
sizeof(*realimagInput) * (rows + 2))) ||
417 !(realimagOutput = (
double *)malloc(
sizeof(*realimagOutput) * (rows + 2))))
422 realFFT2(realimagInput, inputData, rows, 0);
423 frequencies = rows / 2 + 1;
427 length = ((double)rows) * (timeData[rows - 1] - timeData[0]) / ((double)rows - 1.0);
428 dfrequency = factor = 1.0 / length;
430 for (stage = 0; stage < filterStages; stage++) {
431 if (!applyFilterStage(realimagOutput, realimagInput, frequencies, dfrequency, filterStage + stage))
433 SWAP_PTR(realimagOutput, realimagInput);
440 for (row = 0; row < rows; row++) {
441 fprintf(stdout,
"Real: %f, Imag: %f\n", realimagInput[2 * row], realimagInput[2 * row + 1]);
444 realFFT2(realimagOutput, realimagInput, rows, INVERSE_FFT);
446 for (row = 0; row < rows; row++)
447 outputData[row] = realimagOutput[row];
449 free(realimagOutput);
455long applyFilterStage(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
FILTER_STAGE *filterStage) {
458 for (i = 0; i < 2 * frequencies; i++)
461 for (ifilter = 0; ifilter < filterStage->filters; ifilter++) {
462 switch (filterStage->filter[ifilter].filterType) {
464 addClipFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
467 addThresholdFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
470 addHighPassFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
473 addLowPassFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
476 addNotchFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
479 addBandPassFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
482 addFileFilterOutput(outputRI, inputRI, frequencies, dfrequency, filterStage->filter[ifilter].filter);
485 SDDS_Bomb(
"unknown filter type in applyFilterStage--this shouldn't happen");
492void addClipFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
CLIP_FILTER *filter) {
496 i2 = frequencies - 1;
497 if (filter->flags & FILT_HIGH_GIVEN)
498 if ((i2 = frequencies - filter->high) < 0)
500 if (filter->flags & FILT_LOW_GIVEN)
501 if ((i1 = filter->low) >= frequencies)
502 i1 = frequencies - 1;
503 for (; i1 <= i2; i1++) {
504 outputRI[2 * i1] += inputRI[2 * i1];
505 outputRI[2 * i1 + 1] += inputRI[2 * i1 + 1];
509void addThresholdFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
THRESHOLD_FILTER *filter) {
511 double level2, level2q, level2o;
515 if (filter->flags & FILT_START_GIVEN)
516 i1 = computeIndex(filter->start, dfrequency, frequencies);
517 i2 = frequencies - 1;
518 if (filter->flags & FILT_END_GIVEN)
519 i2 = computeIndex(filter->end, dfrequency, frequencies);
521 if (filter->flags & FILT_FRACTHRES_GIVEN) {
523 for (i = i1; i <= i2; i++)
524 if ((mag2 = inputRI[2 * i] * inputRI[2 * i] + inputRI[2 * i + 1] * inputRI[2 * i + 1]) > max2)
526 level2o = max2 * sqr(filter->level);
528 level2o = sqr(filter->level);
529 level2q = level2o / 4;
531 for (i = i1; i <= i2; i++) {
533 if (i == 0 || i == frequencies - 1)
535 if ((inputRI[2 * i] * inputRI[2 * i] + inputRI[2 * i + 1] * inputRI[2 * i + 1]) >= level2) {
536 outputRI[2 * i] += inputRI[2 * i];
537 outputRI[2 * i + 1] += inputRI[2 * i + 1];
542void addHighPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
HILO_FILTER *filter) {
544 double fraction, dfraction;
546 i1 = computeIndex(filter->start, dfrequency, frequencies);
547 i2 = computeIndex(filter->end, dfrequency, frequencies);
549 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
551 for (i = i1; i <= i2; i++) {
552 outputRI[2 * i] += inputRI[2 * i] * fraction;
553 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
554 if ((fraction += dfraction) > 1)
557 for (; i < frequencies; i++) {
558 outputRI[2 * i] += inputRI[2 * i];
559 outputRI[2 * i + 1] += inputRI[2 * i + 1];
563void addLowPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
HILO_FILTER *filter) {
565 double fraction, dfraction;
567 i1 = computeIndex(filter->start, dfrequency, frequencies);
568 i2 = computeIndex(filter->end, dfrequency, frequencies);
570 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
572 for (i = i1; i <= i2; i++) {
573 outputRI[2 * i] += inputRI[2 * i] * fraction;
574 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
575 if ((fraction -= dfraction) < 0)
578 for (i = 0; i < i1; i++) {
579 outputRI[2 * i] += inputRI[2 * i];
580 outputRI[2 * i + 1] += inputRI[2 * i + 1];
584void addNotchFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
NHBP_FILTER *filter) {
586 double fraction, dfraction;
588 i1 = computeIndex(filter->center - filter->fullwidth / 2, dfrequency, frequencies);
589 i2 = computeIndex(filter->center - filter->flatwidth / 2, dfrequency, frequencies);
590 for (i = 0; i < i1; i++) {
591 outputRI[2 * i] += inputRI[2 * i];
592 outputRI[2 * i + 1] += inputRI[2 * i + 1];
594 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
596 for (i = i1; i <= i2; i++) {
597 outputRI[2 * i] += inputRI[2 * i] * fraction;
598 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
599 if ((fraction -= dfraction) < 0)
603 i1 = computeIndex(filter->center + filter->flatwidth / 2, dfrequency, frequencies);
604 i2 = computeIndex(filter->center + filter->fullwidth / 2, dfrequency, frequencies);
605 for (i = i2; i < frequencies; i++) {
606 outputRI[2 * i] += inputRI[2 * i];
607 outputRI[2 * i + 1] += inputRI[2 * i + 1];
609 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
611 for (i = i1; i <= i2; i++) {
612 outputRI[2 * i] += inputRI[2 * i] * fraction;
613 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
614 if ((fraction += dfraction) > 1)
619void addBandPassFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
NHBP_FILTER *filter) {
621 double fraction, dfraction;
623 i1 = computeIndex(filter->center - filter->fullwidth / 2, dfrequency, frequencies);
624 i2 = computeIndex(filter->center - filter->flatwidth / 2, dfrequency, frequencies);
625 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
627 for (i = i1; i <= i2; i++) {
628 outputRI[2 * i] += inputRI[2 * i] * fraction;
629 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
630 if ((fraction += dfraction) > 1)
634 i1 = computeIndex(filter->center + filter->flatwidth / 2, dfrequency, frequencies);
635 i2 = computeIndex(filter->center + filter->fullwidth / 2, dfrequency, frequencies);
636 dfraction = i1 == i2 ? 0 : 1.0 / (i2 - i1);
638 for (i = i1; i <= i2; i++) {
639 outputRI[2 * i] += inputRI[2 * i] * fraction;
640 outputRI[2 * i + 1] += inputRI[2 * i + 1] * fraction;
641 if ((fraction -= dfraction) < 0)
645 i1 = computeIndex(filter->center - filter->flatwidth / 2, dfrequency, frequencies);
646 i2 = computeIndex(filter->center + filter->flatwidth / 2, dfrequency, frequencies);
647 for (i = i1; i <= i2; i++) {
648 outputRI[2 * i] += inputRI[2 * i];
649 outputRI[2 * i + 1] += inputRI[2 * i + 1];
653void addFileFilterOutput(
double *outputRI,
double *inputRI, int64_t frequencies,
double dfrequency,
FILE_FILTER *filter) {
656 double factor, ifactor, rfactor, rdata, idata, f;
658 if (!filter->freqData) {
665 fprintf(stderr,
"error: unable to read filter file %s (sddsfdfilter)\n", filter->file);
669 fprintf(stderr,
"error: file %s has no data on first page (sddsfdfilter)\n", filter->file);
678 for (i = 1; i < filter->points; i++)
679 if (filter->freqData[i - 1] >= filter->freqData[i]) {
680 fprintf(stderr,
"error: frequency data not monotonically increasing for %s (sddsfdfilter)\n", filter->file);
684 for (i = 0; i < frequencies; i++) {
686 if (filter->freqData[0] > f || filter->freqData[filter->points - 1] < f)
688 if (filter->magName) {
689 factor =
interp(filter->magData, filter->freqData, filter->points, f, 0, 1, &code);
690 outputRI[2 * i] += factor * inputRI[2 * i];
691 outputRI[2 * i + 1] += factor * inputRI[2 * i + 1];
693 rfactor =
interp(filter->realData, filter->freqData, filter->points, f, 0, 1, &code);
694 ifactor =
interp(filter->imagData, filter->freqData, filter->points, f, 0, 1, &code);
695 rdata = inputRI[2 * i];
696 idata = inputRI[2 * i + 1];
697 outputRI[2 * i] += rdata * rfactor - idata * ifactor;
698 outputRI[2 * i + 1] += rdata * ifactor + idata * rfactor;
703int64_t computeIndex(
double value,
double dfrequency, int64_t frequencies) {
706 i1 = value / dfrequency + 0.5;
709 if (i1 > frequencies - 1)
710 i1 = frequencies - 1;
714void addFilter(
FILTER_STAGE *filterStage,
long optionCode, SCANNED_ARG *scanned) {
724 if (!(filterStage->filter =
SDDS_Realloc(filterStage->filter,
sizeof(*filterStage->filter) * (filterStage->filters + 1))))
725 SDDS_Bomb(
"allocation failure adding filter slot");
726 filter = filterStage->filter;
727 filters = filterStage->filters;
728 filterStage->filters++;
730 items = scanned->n_items - 1;
731 item = scanned->list + 1;
732 switch (filter[filters].filterType = optionCode) {
734 if (!(thresholdFilter = filter[filters].filter = calloc(1,
sizeof(
THRESHOLD_FILTER))))
735 SDDS_Bomb(
"allocation failure allocating threshold filter");
738 if (!
scanItemList(&thresholdFilter->flags, item, &items, 0,
739 "level",
SDDS_DOUBLE, &thresholdFilter->level, 1, FILT_LEVEL_GIVEN,
740 "fractional", -1, NULL, 0, FILT_FRACTHRES_GIVEN,
741 "start",
SDDS_DOUBLE, &thresholdFilter->start, 1, FILT_START_GIVEN,
742 "end",
SDDS_DOUBLE, &thresholdFilter->end, 1, FILT_END_GIVEN, NULL))
743 SDDS_Bomb(
"invalid -threshold syntax/values");
744 if (!(thresholdFilter->flags & FILT_LEVEL_GIVEN))
745 SDDS_Bomb(
"supply level=<value> qualifier for -threshold");
746 if ((thresholdFilter->flags & FILT_START_GIVEN && thresholdFilter->flags & FILT_END_GIVEN) && thresholdFilter->start > thresholdFilter->end)
747 SDDS_Bomb(
"start > end for -threshold filter");
751 if (!(hiloFilter = filter[filters].filter = calloc(1,
sizeof(
HILO_FILTER))))
752 SDDS_Bomb(
"allocation failure allocating low-pass or high-pass filter");
754 "start",
SDDS_DOUBLE, &hiloFilter->start, 1, FILT_START_GIVEN,
755 "end",
SDDS_DOUBLE, &hiloFilter->end, 1, FILT_END_GIVEN, NULL))
756 SDDS_Bomb(
"invalid -highpass or -lowpass syntax");
757 if (!(hiloFilter->flags & FILT_START_GIVEN) || !(hiloFilter->flags & FILT_END_GIVEN))
758 SDDS_Bomb(
"supply start=<value> and end=<value> qualifiers with -highpass and -lowpass");
762 if (!(nhbpFilter = filter[filters].filter = calloc(1,
sizeof(
NHBP_FILTER))))
763 SDDS_Bomb(
"allocation failure allocating notch or bandpass filter");
765 "center",
SDDS_DOUBLE, &nhbpFilter->center, 1, FILT_CENTER_GIVEN,
766 "fullwidth",
SDDS_DOUBLE, &nhbpFilter->fullwidth, 1, FILT_FULLWIDTH_GIVEN,
767 "flatwidth",
SDDS_DOUBLE, &nhbpFilter->flatwidth, 1, FILT_FLATWIDTH_GIVEN, NULL))
768 SDDS_Bomb(
"invalid -notch or -bandpass syntax");
769 if (!(nhbpFilter->flags & FILT_CENTER_GIVEN) || !(nhbpFilter->flags & FILT_FLATWIDTH_GIVEN))
770 SDDS_Bomb(
"supply center=<value> and flatWidth=<value> qualifiers with -notch and -bandpass");
771 if (!(nhbpFilter->flags & FILT_FULLWIDTH_GIVEN))
772 nhbpFilter->fullwidth = nhbpFilter->flatwidth;
773 if (nhbpFilter->fullwidth < nhbpFilter->flatwidth)
774 SDDS_Bomb(
"full width may not be less than flat width for notch/bandpass filter");
777 if (!(fileFilter = filter[filters].filter = calloc(1,
sizeof(
FILE_FILTER))))
778 SDDS_Bomb(
"allocation failure allocating file filter");
780 "filename",
SDDS_STRING, &fileFilter->file, 1, FILT_FILENAME_GIVEN,
781 "frequency",
SDDS_STRING, &fileFilter->freqName, 1, FILT_FREQNAME_GIVEN,
782 "real",
SDDS_STRING, &fileFilter->realName, 1, FILT_REALNAME_GIVEN,
783 "imaginary",
SDDS_STRING, &fileFilter->imagName, 1, FILT_IMAGNAME_GIVEN,
784 "magnitude",
SDDS_STRING, &fileFilter->magName, 1, FILT_MAGNAME_GIVEN, NULL))
786 if (!(fileFilter->flags & FILT_FILENAME_GIVEN))
787 SDDS_Bomb(
"supply filename=<string> with -filterFile");
788 if (!(fileFilter->flags & FILT_FREQNAME_GIVEN))
789 SDDS_Bomb(
"supply frequency=<columnName> with -filterFile");
790 if (!(fileFilter->flags & FILT_MAGNAME_GIVEN) && !(fileFilter->flags & FILT_REALNAME_GIVEN && fileFilter->flags & FILT_IMAGNAME_GIVEN))
791 SDDS_Bomb(
"supply either magnitude=<columnName>, or real=<columnName> and imag=<columnName>, with -filterFile");
792 if (fileFilter->flags & FILT_MAGNAME_GIVEN && (fileFilter->flags & FILT_REALNAME_GIVEN || fileFilter->flags & FILT_IMAGNAME_GIVEN))
793 SDDS_Bomb(
"magnitude=<columnName> is incompatible with real=<columnName> and imag=<columnName> for -filterFile");
794 fileFilter->freqData = NULL;
797 if (!(clipFilter = filter[filters].filter = calloc(1,
sizeof(
CLIP_FILTER))))
798 SDDS_Bomb(
"allocation failure allocating clip filter");
800 "high",
SDDS_LONG, &clipFilter->high, 1, FILT_HIGH_GIVEN,
801 "low",
SDDS_LONG, &clipFilter->low, 1, FILT_LOW_GIVEN, NULL))
802 SDDS_Bomb(
"invalid -clipFrequencies syntax");
803 if (!(clipFilter->flags & FILT_HIGH_GIVEN) && !(clipFilter->flags & FILT_LOW_GIVEN))
804 SDDS_Bomb(
"supply at least one of high=<number> or low=<number> with -clipFrequencies");
807 SDDS_Bomb(
"invalid filter code---this shouldn't happen");
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric 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.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
double interp(double *f, double *x, long n, double xo, long warnings, long order, long *returnCode)
Performs simple linear interpolation of data.
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.