24#include "match_string.h"
38char *commandline_option[N_OPTIONS] = {
47 "Usage: sddsrespmatrixderivative <inputfile> <outputfile> [OPTIONS]\n\n"
49 " -pipe=[input][,output] Read input from and/or write output to a pipe.\n"
50 " -mode=<string> Specify the mode of derivative:\n"
51 " \"cor\" - derivative with respect to correctors\n"
52 " \"bpm\" - derivative with respect to BPMs\n"
53 " \"quad\" - add rows related to quad constraints\n"
54 " -addRowsBefore=<number> Number of zero rows to add before the meaningful rows of output.\n"
56 " If mode=quad, it specifies the column number where the diagonal output starts.\n"
57 " -addRowsAfter=<number> Number of zero rows to add after the meaningful rows of output.\n"
59 " If mode=quad, it specifies the number of rows of diagonal output.\n"
60 " -verbose Print incidental information to stderr.\n";
62char **TokenizeString(
char *source,
long n_items);
63char *JoinStrings(
char **source,
long n_items,
long buflen_increment);
64int MakeDerivative(
char *mode,
int addRowsBefore,
int addRowsAfter,
int addColumnsBefore, MATRIX *B, MATRIX *A);
65int MakeRootnameColumn(
char *mode,
long inputDoubleColumns, int64_t inputRows,
long addRowsBefore,
long addRowsAfter,
66 char **inputDoubleColumnName,
char **stringData,
char **rootnameData);
68int main(
int argc,
char **argv) {
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;
82#define BUFFER_SIZE_INCREMENT 16384
84 long OldStringColumnsDefined;
87 unsigned long pipeFlags;
88 long tmpfile_used, noWarnings;
89 long ipage, columnType;
90 long addRowsBefore, addRowsAfter, addColumnsBefore;
92 char **stringData = NULL;
93 char **rootnameData = NULL;
95 inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
96 outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;
100 argc =
scanargs(&s_arg, argc, argv);
104 inputfile = outputfile = NULL;
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)) {
123 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
128 if (!(mode = s_arg[i_arg].list[1]))
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");
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");
140 bomb(
"Unrecognized option provided", USAGE);
144 inputfile = s_arg[i_arg].list[0];
145 else if (!outputfile)
146 outputfile = s_arg[i_arg].list[0];
148 bomb(
"Too many filenames provided", USAGE);
153 if (strcmp(mode,
"cor") && strcmp(mode,
"bpm") && strcmp(mode,
"quad")) {
154 bomb(
"Invalid mode parameter",
"Mode must be 'cor', 'bpm', or 'quad'");
157 bomb(
"Mode parameter is not defined.",
"Mode must be 'cor', 'bpm', or 'quad'");
160 processFilenames(
"sddsrespmatrixderivative", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
170 inputDoubleColumns = 0;
171 inputStringColumns = 0;
172 inputDoubleColumnName = (
char **)malloc(inputColumns *
sizeof(
char *));
173 inputStringColumnName = (
char **)malloc(inputColumns *
sizeof(
char *));
176 if (strcmp(mode,
"quad") == 0) {
177 addColumnsBefore = addRowsBefore;
180 addColumnsBefore = 0;
184 while (0 < (ipage = SDDS_ReadTable(&inputPage))) {
190 for (i = 0; i < inputColumns; i++) {
192 inputDoubleColumnName[inputDoubleColumns] = inputColumnName[i];
193 inputDoubleColumns++;
195 inputStringColumnName[inputStringColumns] = inputColumnName[i];
196 inputStringColumns++;
206 if (inputDoubleColumns == 0)
207 SDDS_Bomb(
"No numerical columns in file.");
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);
216 if (inputDoubleColumns) {
217 m_alloc(&R, inputDoubleColumns, inputRows);
218 outputRows = inputDoubleColumns * inputRows + addRowsBefore + addRowsAfter;
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);
225 outputRows = addRowsAfter;
226 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
229 for (col = 0; col < inputDoubleColumns; col++) {
236 if (strcmp(mode,
"quad") != 0) {
245 if ((ipage == 1) && verbose) {
246 fprintf(stderr,
"Starting MakeDerivative...\n");
249 MakeDerivative(mode, addRowsBefore, addRowsAfter, addColumnsBefore, Rderiv, R);
251 rootnameData = (
char **)malloc(outputRows *
sizeof(
char *));
252 if ((ipage == 1) && verbose) {
253 fprintf(stderr,
"Starting MakeRootnameColumn...\n");
256 MakeRootnameColumn(mode, inputDoubleColumns, inputRows, addRowsBefore, addRowsAfter,
257 inputDoubleColumnName, stringData, rootnameData);
260 if ((ipage == 1) && verbose) {
261 fprintf(stderr,
"Starting output...\n");
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;
272 outputDoubleColumns = inputDoubleColumns;
273 outputDoubleColumnName = inputDoubleColumnName;
276 if (!
SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, outputfile))
280 outputStringColumns = 1;
281 outputStringColumnName = (
char **)malloc(
sizeof(
char *));
282 outputStringColumnName[0] =
"Rootname";
287 for (i = 0; i < outputDoubleColumns; i++) {
294 case SDDS_CHECK_NONEXISTENT:
306 if (!SDDS_StartTable(&outputPage, outputRows))
310 if (!
SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
"InputFile", inputfile ? inputfile :
"pipe", NULL))
317 if (!
SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, rootnameData, outputRows, outputStringColumnName[0]))
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]))
327 if (!SDDS_WriteTable(&outputPage))
330 if (outputDoubleColumns) {
347int MakeRootnameColumn(
char *mode,
long inputDoubleColumns, int64_t inputRows,
long addRowsBefore,
long addRowsAfter,
348 char **inputDoubleColumnName,
char **stringData,
char **rootnameData) {
352 for (i = 0; i < addRowsBefore; i++) {
353 rootnameData[n] = (
char *)malloc(
sizeof(
char) * 1);
354 rootnameData[n][0] =
'\0';
358 if (strcmp(mode,
"quad") == 0) {
359 for (i = 0; i < addRowsAfter; i++) {
360 if (addRowsAfter > inputDoubleColumns) {
361 SDDS_SetError(
"Number of addRowsAfter is greater than number of input columns in quad mode.");
365 rootnameData[n] = (
char *)malloc(
sizeof(
char) * (strlen(inputDoubleColumnName[i]) + 1));
366 strcpy(rootnameData[n], inputDoubleColumnName[i]);
370 for (i = 0; i < inputRows; i++) {
371 for (j = 0; j < inputDoubleColumns; j++) {
372 size_t len = strlen(inputDoubleColumnName[j]) + strlen(stringData[i]) + 1;
373 rootnameData[n] = (
char *)malloc(
sizeof(
char) * (len + 1));
374 strcpy(rootnameData[n], inputDoubleColumnName[j]);
375 strcat(rootnameData[n], stringData[i]);
380 for (i = 0; i < addRowsAfter; i++) {
381 rootnameData[n] = (
char *)malloc(
sizeof(
char) * 1);
382 rootnameData[n][0] =
'\0';
392int MakeDerivative(
char *mode,
int addRowsBefore,
int addRowsAfter,
int addColumnsBefore, MATRIX *B, MATRIX *A) {
400 for (i = 0; i < B->n; i++) {
401 for (j = 0; j < B->m; j++) {
406 if (strcmp(mode,
"cor") == 0) {
407 for (i = 0; i < Ncols; i++) {
408 for (j = 0; j < Nrows; j++) {
409 B->a[i][i + j * Ncols + addRowsBefore] = A->a[i][j];
412 }
else if (strcmp(mode,
"bpm") == 0) {
413 for (i = 0; i < Nrows; i++) {
414 for (j = 0; j < Ncols; j++) {
415 B->a[i][i * Ncols + j + addRowsBefore] = A->a[j][i];
419 for (i = 0; i < addRowsAfter; i++) {
420 B->a[i + addColumnsBefore][i] = 1.0;
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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)