68 {
69 SCANNED_ARG *s_arg;
71
72 char *inputfile, *outputfile;
73 char **inputColumnName, **inputStringColumnName, **inputDoubleColumnName;
74 char **outputStringColumnName, **outputDoubleColumnName;
75 int64_t inputRows, outputRows;
76 long inputDoubleColumns, inputStringColumns;
77 long outputDoubleColumns, outputStringColumns;
78 char **inputParameterName;
79 int32_t inputParameters, inputColumns;
80 char *inputDescription, *inputContents;
81 long i, i_arg, col;
82#define BUFFER_SIZE_INCREMENT 16384
83 MATRIX *R, *Rderiv;
84 long OldStringColumnsDefined;
85 long verbose;
86 long ascii;
87 unsigned long pipeFlags;
88 long tmpfile_used, noWarnings;
89 long ipage, columnType;
90 long addRowsBefore, addRowsAfter, addColumnsBefore;
91 char *mode;
92 char **stringData = NULL;
93 char **rootnameData = NULL;
94
95 inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
96 outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;
97
99
100 argc =
scanargs(&s_arg, argc, argv);
101 if (argc == 1)
103
104 inputfile = outputfile = NULL;
105 verbose = 0;
106 ascii = 0;
107 pipeFlags = 0;
108 tmpfile_used = 0;
109 noWarnings = 0;
110 mode = NULL;
111 int modeDefined = 0;
112 addRowsBefore = 0;
113 addRowsAfter = 0;
114
115 for (i_arg = 1; i_arg < argc; i_arg++) {
116 if (s_arg[i_arg].arg_type == OPTION) {
118 switch (
match_string(s_arg[i_arg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
119 case CLO_VERBOSE:
120 verbose = 1;
121 break;
122 case CLO_PIPE:
123 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
125 break;
126 case CLO_MODE:
127 modeDefined = 1;
128 if (!(mode = s_arg[i_arg].list[1]))
130 break;
131 case CLO_ADDROWSBEFORE:
132 if (!(sscanf(s_arg[i_arg].list[1], "%ld", &addRowsBefore)) || (addRowsBefore < 0))
133 SDDS_Bomb(
"Invalid value for addRowsBefore: must be a non-negative number");
134 break;
135 case CLO_ADDROWSAFTER:
136 if (!(sscanf(s_arg[i_arg].list[1], "%ld", &addRowsAfter)) || (addRowsAfter < 0))
137 SDDS_Bomb(
"Invalid value for addRowsAfter: must be a non-negative number");
138 break;
139 default:
140 bomb(
"Unrecognized option provided", USAGE);
141 }
142 } else {
143 if (!inputfile)
144 inputfile = s_arg[i_arg].list[0];
145 else if (!outputfile)
146 outputfile = s_arg[i_arg].list[0];
147 else
148 bomb(
"Too many filenames provided", USAGE);
149 }
150 }
151
152 if (modeDefined) {
153 if (strcmp(mode, "cor") && strcmp(mode, "bpm") && strcmp(mode, "quad")) {
154 bomb(
"Invalid mode parameter",
"Mode must be 'cor', 'bpm', or 'quad'");
155 }
156 } else {
157 bomb(
"Mode parameter is not defined.",
"Mode must be 'cor', 'bpm', or 'quad'");
158 }
159
160 processFilenames(
"sddsrespmatrixderivative", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
161
167 exit(EXIT_FAILURE);
168 }
169
170 inputDoubleColumns = 0;
171 inputStringColumns = 0;
172 inputDoubleColumnName = (char **)malloc(inputColumns * sizeof(char *));
173 inputStringColumnName = (char **)malloc(inputColumns * sizeof(char *));
174 inputRows = 0;
175
176 if (strcmp(mode, "quad") == 0) {
177 addColumnsBefore = addRowsBefore;
178 addRowsBefore = 0;
179 } else {
180 addColumnsBefore = 0;
181 }
182
183
184 while (0 < (ipage = SDDS_ReadTable(&inputPage))) {
185 if (ipage == 1) {
188
189
190 for (i = 0; i < inputColumns; i++) {
192 inputDoubleColumnName[inputDoubleColumns] = inputColumnName[i];
193 inputDoubleColumns++;
195 inputStringColumnName[inputStringColumns] = inputColumnName[i];
196 inputStringColumns++;
197 }
198 }
199
202 } else {
204 }
205
206 if (inputDoubleColumns == 0)
207 SDDS_Bomb(
"No numerical columns in file.");
208
209 if ((ipage == 1) && verbose) {
210 fprintf(stderr, "Number of numerical columns: %ld.\n", inputDoubleColumns);
211 fprintf(stderr, "Number of string columns: %ld.\n", inputStringColumns);
212 fprintf(stderr, "Number of rows: %" PRId64 ".\n", inputRows);
213 }
214
215
216 if (inputDoubleColumns) {
217 m_alloc(&R, inputDoubleColumns, inputRows);
218 outputRows = inputDoubleColumns * inputRows + addRowsBefore + addRowsAfter;
219
220 if (strcmp(mode, "cor") == 0) {
221 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
222 } else if (strcmp(mode, "bpm") == 0) {
223 m_alloc(&Rderiv, inputRows, outputRows);
224 } else {
225 outputRows = addRowsAfter;
226 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
227 }
228
229 for (col = 0; col < inputDoubleColumns; col++) {
232 }
233 }
234
235
236 if (strcmp(mode, "quad") != 0) {
240 return EXIT_FAILURE;
241 }
242 }
243 }
244
245 if ((ipage == 1) && verbose) {
246 fprintf(stderr, "Starting MakeDerivative...\n");
247 }
248
249 MakeDerivative(mode, addRowsBefore, addRowsAfter, addColumnsBefore, Rderiv, R);
250
251 rootnameData = (char **)malloc(outputRows * sizeof(char *));
252 if ((ipage == 1) && verbose) {
253 fprintf(stderr, "Starting MakeRootnameColumn...\n");
254 }
255
256 MakeRootnameColumn(mode, inputDoubleColumns, inputRows, addRowsBefore, addRowsAfter,
257 inputDoubleColumnName, stringData, rootnameData);
258
259
260 if ((ipage == 1) && verbose) {
261 fprintf(stderr, "Starting output...\n");
262 }
263
264 if (ipage == 1) {
265 if (strcmp(mode, "cor") == 0) {
266 outputDoubleColumns = inputDoubleColumns;
267 outputDoubleColumnName = inputDoubleColumnName;
268 } else if (strcmp(mode, "bpm") == 0) {
269 outputDoubleColumns = inputRows;
270 outputDoubleColumnName = stringData;
271 } else {
272 outputDoubleColumns = inputDoubleColumns;
273 outputDoubleColumnName = inputDoubleColumnName;
274 }
275
276 if (!
SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, outputfile))
278
279
280 outputStringColumns = 1;
281 outputStringColumnName = (char **)malloc(sizeof(char *));
282 outputStringColumnName[0] = "Rootname";
285
286
287 for (i = 0; i < outputDoubleColumns; i++) {
290 }
291
292
294 case SDDS_CHECK_NONEXISTENT:
297 break;
298 default:
299 break;
300 }
301
304 }
305
306 if (!SDDS_StartTable(&outputPage, outputRows))
308
309 if (ipage == 1) {
310 if (!
SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
"InputFile", inputfile ? inputfile :
"pipe", NULL))
312 }
313
314
315
316
317 if (!
SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, rootnameData, outputRows, outputStringColumnName[0]))
319
320
321 for (i = 0; i < outputDoubleColumns; i++) {
322 if (!
SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, Rderiv->a[i], outputRows, outputDoubleColumnName[i]))
324 }
325 }
326
327 if (!SDDS_WriteTable(&outputPage))
329
330 if (outputDoubleColumns) {
331 m_free(&R);
332 m_free(&Rderiv);
333 free(rootnameData);
334 }
335
338
340 exit(EXIT_FAILURE);
341
342 return EXIT_SUCCESS;
343}
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
void SDDS_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.
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.
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
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)