60char *option[N_OPTIONS] =
71 "sddszerofind [<inputfile>] [<outputfile>] [-pipe=[input][,output]]\n"
72 "-zeroesOf=<columnName> [-columns=<columnNames>] [-offset=<value>] "
73 "[-slopeOutput] [-majorOrder=row|column]\n\n"
74 "Finds values of columns of data at interpolated zero positions in another\n"
76 "-zeroesOf Specifies the column for which to find zeroes.\n"
77 "-offset Specifies a value to add to the values of the -zeroesOf column\n"
78 " prior to finding the zeroes. -offset=1 will find places where\n"
79 " the original values are -1.\n"
80 "-columns Specifies the columns to interpolate at the zero positions.\n"
81 " Default is all numerical columns in the file.\n"
82 "-majorOrder Specify output file in row or column order.\n"
83 "-slopeOutput Provide output of the slope of each -column column at the zero\n"
85 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
87#define FL_SLOPEOUTPUT 0x00001UL
89long resolve_column_names(
SDDS_DATASET *SDDSin,
char *depen_quantity,
char ***indep_quantity, int32_t *indep_quantities);
91int main(
int argc,
char **argv) {
94 char *input = NULL, *output = NULL, *zero_name = NULL, **column_name = NULL;
95 long i_arg, page_returned;
97 int32_t column_names = 0;
98 double **indep_data, *depen_data, **slope_data, slope, offset = 0;
99 unsigned long pipe_flags = 0, flags = 0, major_order_flag;
100 char s[SDDS_MAXLINE];
101 short column_major_order = -1;
104 argc =
scanargs(&s_arg, argc, argv);
105 if (argc < 2 || argc > (2 + N_OPTIONS)) {
109 for (i_arg = 1; i_arg < argc; i_arg++) {
110 if (s_arg[i_arg].arg_type == OPTION) {
111 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
112 case CLO_MAJOR_ORDER:
113 major_order_flag = 0;
114 s_arg[i_arg].n_items--;
115 if (s_arg[i_arg].n_items > 0 &&
116 (!
scanItemList(&major_order_flag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
117 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
118 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
119 SDDS_Bomb(
"invalid -majorOrder syntax/values");
121 column_major_order = (major_order_flag & SDDS_COLUMN_MAJOR_ORDER) ? 1 : 0;
124 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipe_flags)) {
129 if (s_arg[i_arg].n_items != 2) {
132 zero_name = s_arg[i_arg].list[1];
135 if (s_arg[i_arg].n_items < 2) {
138 column_name =
tmalloc(
sizeof(*column_name) * (column_names = s_arg[i_arg].n_items - 1));
139 for (
int i = 0; i < column_names; i++) {
140 column_name[i] = s_arg[i_arg].list[i + 1];
143 case CLO_SLOPEOUTPUT:
144 flags |= FL_SLOPEOUTPUT;
147 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%le", &offset) != 1) {
152 fprintf(stderr,
"Error (%s): unknown/ambiguous option: %s\n", argv[0], s_arg[i_arg].list[0]);
157 input = s_arg[i_arg].list[0];
158 }
else if (output == NULL) {
159 output = s_arg[i_arg].list[0];
169 SDDS_Bomb(
"-zeroesOf option must be given");
176 if (!resolve_column_names(&in_set, zero_name, &column_name, &column_names) ||
182 out_set.layout.data_mode.column_major = (column_major_order != -1) ? column_major_order : in_set.layout.data_mode.column_major;
184 for (
int i = 0; i < column_names; i++) {
185 snprintf(s, SDDS_MAXLINE,
"%sSlope", column_name[i]);
196 indep_data =
tmalloc(
sizeof(*indep_data) * column_names);
197 slope_data =
tmalloc(
sizeof(*slope_data) * column_names);
210 for (
int i = 0; i < column_names; i++) {
212 if (!indep_data[i]) {
216 if (flags & FL_SLOPEOUTPUT) {
217 slope_data[i] =
tmalloc(
sizeof(**slope_data) * rows);
222 for (
int row = 0; row < rows; row++) {
223 depen_data[row] += offset;
228 for (
int row = 0; row < rows - 1; row++) {
229 if ((depen_data[row] <= 0 && depen_data[row + 1] >= 0) ||
230 (depen_data[row] >= 0 && depen_data[row + 1] <= 0)) {
231 for (
int i = 0; i < column_names; i++) {
232 if (indep_data[i][row] == indep_data[i][row + 1]) {
233 if (flags & FL_SLOPEOUTPUT) {
234 slope_data[i][zrow] = DBL_MAX;
236 indep_data[i][zrow] = indep_data[i][row];
238 slope = (depen_data[row + 1] - depen_data[row]) / (indep_data[i][row + 1] - indep_data[i][row]);
239 if (flags & FL_SLOPEOUTPUT) {
240 slope_data[i][zrow] = slope;
242 indep_data[i][zrow] = (slope) ? (indep_data[i][row] - depen_data[row] / slope) : ((indep_data[i][row] + indep_data[i][row + 1]) / 2);
245 depen_data[zrow] = -offset;
256 for (
int i = 0; i < column_names; i++) {
257 snprintf(s, SDDS_MAXLINE,
"%sSlope", column_name[i]);
266 for (
int i = 0; i < column_names; i++) {
269 if (flags & FL_SLOPEOUTPUT) {
270 for (
int i = 0; i < column_names; i++) {
289long resolve_column_names(
SDDS_DATASET *SDDSin,
char *depen_quantity,
char ***indep_quantity, int32_t *indep_quantities) {
291 char s[SDDS_MAXLINE];
295 snprintf(s, SDDS_MAXLINE,
"column %s is non-existent or non-numeric", depen_quantity);
300 if (*indep_quantities) {
302 for (
long i = 0; i < *indep_quantities; i++) {
313 if (!(*indep_quantity) || *indep_quantities == 0) {
317 for (
long i = 0; i < *indep_quantities; i++) {
326 free(*indep_quantity);
328 if (!(*indep_quantity) || *indep_quantities == 0) {
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_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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_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_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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
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.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric 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.
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.