51#include "match_string.h"
65char *commandline_option[N_OPTIONS] = {
74 "sddsrespmatrixderivative [<inputfile>] [<outputfile>]\n"
75 " [-pipe=[input][,output]]\n"
77 " [-addRowsBefore=<number>] \n"
78 " [-addRowsAfter=<number>] \n"
81 " -pipe=[input][,output] Read input from and/or write output to a pipe.\n"
82 " -mode=<string> Specify the mode of derivative:\n"
83 " \"cor\" - derivative with respect to correctors\n"
84 " \"bpm\" - derivative with respect to BPMs\n"
85 " \"quad\" - add rows related to quad constraints\n"
86 " -addRowsBefore=<number> Number of zero rows to add before the meaningful rows of output.\n"
88 " If mode=quad, it specifies the column number where the diagonal output starts.\n"
89 " -addRowsAfter=<number> Number of zero rows to add after the meaningful rows of output.\n"
91 " If mode=quad, it specifies the number of rows of diagonal output.\n"
92 " -verbose Print incidental information to stderr.\n";
94char **TokenizeString(
char *source,
long n_items);
95char *JoinStrings(
char **source,
long n_items,
long buflen_increment);
96int MakeDerivative(
char *mode,
int addRowsBefore,
int addRowsAfter,
int addColumnsBefore, MATRIX *B, MATRIX *A);
97int MakeRootnameColumn(
char *mode,
long inputDoubleColumns, int64_t inputRows,
long addRowsBefore,
long addRowsAfter,
98 char **inputDoubleColumnName,
char **stringData,
char **rootnameData);
100int main(
int argc,
char **argv) {
104 char *inputfile, *outputfile;
105 char **inputColumnName, **inputStringColumnName, **inputDoubleColumnName;
106 char **outputStringColumnName, **outputDoubleColumnName;
107 int64_t inputRows, outputRows;
108 long inputDoubleColumns, inputStringColumns;
109 long outputDoubleColumns, outputStringColumns;
110 char **inputParameterName;
111 int32_t inputParameters, inputColumns;
112 char *inputDescription, *inputContents;
114#define BUFFER_SIZE_INCREMENT 16384
116 long OldStringColumnsDefined;
119 unsigned long pipeFlags;
120 long tmpfile_used, noWarnings;
121 long ipage, columnType;
122 long addRowsBefore, addRowsAfter, addColumnsBefore;
124 char **stringData = NULL;
125 char **rootnameData = NULL;
127 inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
128 outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;
132 argc =
scanargs(&s_arg, argc, argv);
136 inputfile = outputfile = NULL;
147 for (i_arg = 1; i_arg < argc; i_arg++) {
148 if (s_arg[i_arg].arg_type == OPTION) {
150 switch (
match_string(s_arg[i_arg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
155 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
160 if (!(mode = s_arg[i_arg].list[1]))
163 case CLO_ADDROWSBEFORE:
164 if (!(sscanf(s_arg[i_arg].list[1],
"%ld", &addRowsBefore)) || (addRowsBefore < 0))
165 SDDS_Bomb(
"Invalid value for addRowsBefore: must be a non-negative number");
167 case CLO_ADDROWSAFTER:
168 if (!(sscanf(s_arg[i_arg].list[1],
"%ld", &addRowsAfter)) || (addRowsAfter < 0))
169 SDDS_Bomb(
"Invalid value for addRowsAfter: must be a non-negative number");
172 bomb(
"Unrecognized option provided", USAGE);
176 inputfile = s_arg[i_arg].list[0];
177 else if (!outputfile)
178 outputfile = s_arg[i_arg].list[0];
180 bomb(
"Too many filenames provided", USAGE);
185 if (strcmp(mode,
"cor") && strcmp(mode,
"bpm") && strcmp(mode,
"quad")) {
186 bomb(
"Invalid mode parameter",
"Mode must be 'cor', 'bpm', or 'quad'");
189 bomb(
"Mode parameter is not defined.",
"Mode must be 'cor', 'bpm', or 'quad'");
192 processFilenames(
"sddsrespmatrixderivative", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
202 inputDoubleColumns = 0;
203 inputStringColumns = 0;
204 inputDoubleColumnName = (
char **)malloc(inputColumns *
sizeof(
char *));
205 inputStringColumnName = (
char **)malloc(inputColumns *
sizeof(
char *));
208 if (strcmp(mode,
"quad") == 0) {
209 addColumnsBefore = addRowsBefore;
212 addColumnsBefore = 0;
216 while (0 < (ipage = SDDS_ReadTable(&inputPage))) {
222 for (i = 0; i < inputColumns; i++) {
224 inputDoubleColumnName[inputDoubleColumns] = inputColumnName[i];
225 inputDoubleColumns++;
227 inputStringColumnName[inputStringColumns] = inputColumnName[i];
228 inputStringColumns++;
238 if (inputDoubleColumns == 0)
239 SDDS_Bomb(
"No numerical columns in file.");
241 if ((ipage == 1) && verbose) {
242 fprintf(stderr,
"Number of numerical columns: %ld.\n", inputDoubleColumns);
243 fprintf(stderr,
"Number of string columns: %ld.\n", inputStringColumns);
244 fprintf(stderr,
"Number of rows: %" PRId64
".\n", inputRows);
248 if (inputDoubleColumns) {
249 m_alloc(&R, inputDoubleColumns, inputRows);
250 outputRows = inputDoubleColumns * inputRows + addRowsBefore + addRowsAfter;
252 if (strcmp(mode,
"cor") == 0) {
253 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
254 }
else if (strcmp(mode,
"bpm") == 0) {
255 m_alloc(&Rderiv, inputRows, outputRows);
257 outputRows = addRowsAfter;
258 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
261 for (col = 0; col < inputDoubleColumns; col++) {
268 if (strcmp(mode,
"quad") != 0) {
277 if ((ipage == 1) && verbose) {
278 fprintf(stderr,
"Starting MakeDerivative...\n");
281 MakeDerivative(mode, addRowsBefore, addRowsAfter, addColumnsBefore, Rderiv, R);
283 rootnameData = (
char **)malloc(outputRows *
sizeof(
char *));
284 if ((ipage == 1) && verbose) {
285 fprintf(stderr,
"Starting MakeRootnameColumn...\n");
288 MakeRootnameColumn(mode, inputDoubleColumns, inputRows, addRowsBefore, addRowsAfter,
289 inputDoubleColumnName, stringData, rootnameData);
292 if ((ipage == 1) && verbose) {
293 fprintf(stderr,
"Starting output...\n");
297 if (strcmp(mode,
"cor") == 0) {
298 outputDoubleColumns = inputDoubleColumns;
299 outputDoubleColumnName = inputDoubleColumnName;
300 }
else if (strcmp(mode,
"bpm") == 0) {
301 outputDoubleColumns = inputRows;
302 outputDoubleColumnName = stringData;
304 outputDoubleColumns = inputDoubleColumns;
305 outputDoubleColumnName = inputDoubleColumnName;
308 if (!
SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, outputfile))
312 outputStringColumns = 1;
313 outputStringColumnName = (
char **)malloc(
sizeof(
char *));
314 outputStringColumnName[0] =
"Rootname";
319 for (i = 0; i < outputDoubleColumns; i++) {
326 case SDDS_CHECK_NONEXISTENT:
338 if (!SDDS_StartTable(&outputPage, outputRows))
342 if (!
SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
"InputFile", inputfile ? inputfile :
"pipe", NULL))
349 if (!
SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, rootnameData, outputRows, outputStringColumnName[0]))
353 for (i = 0; i < outputDoubleColumns; i++) {
354 if (!
SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, Rderiv->a[i], outputRows, outputDoubleColumnName[i]))
359 if (!SDDS_WriteTable(&outputPage))
362 if (outputDoubleColumns) {
379int MakeRootnameColumn(
char *mode,
long inputDoubleColumns, int64_t inputRows,
long addRowsBefore,
long addRowsAfter,
380 char **inputDoubleColumnName,
char **stringData,
char **rootnameData) {
384 for (i = 0; i < addRowsBefore; i++) {
385 rootnameData[n] = (
char *)malloc(
sizeof(
char) * 1);
386 rootnameData[n][0] =
'\0';
390 if (strcmp(mode,
"quad") == 0) {
391 for (i = 0; i < addRowsAfter; i++) {
392 if (addRowsAfter > inputDoubleColumns) {
393 SDDS_SetError(
"Number of addRowsAfter is greater than number of input columns in quad mode.");
397 rootnameData[n] = (
char *)malloc(
sizeof(
char) * (strlen(inputDoubleColumnName[i]) + 1));
398 strcpy(rootnameData[n], inputDoubleColumnName[i]);
402 for (i = 0; i < inputRows; i++) {
403 for (j = 0; j < inputDoubleColumns; j++) {
404 size_t len = strlen(inputDoubleColumnName[j]) + strlen(stringData[i]) + 1;
405 rootnameData[n] = (
char *)malloc(
sizeof(
char) * (len + 1));
406 strcpy(rootnameData[n], inputDoubleColumnName[j]);
407 strcat(rootnameData[n], stringData[i]);
412 for (i = 0; i < addRowsAfter; i++) {
413 rootnameData[n] = (
char *)malloc(
sizeof(
char) * 1);
414 rootnameData[n][0] =
'\0';
424int MakeDerivative(
char *mode,
int addRowsBefore,
int addRowsAfter,
int addColumnsBefore, MATRIX *B, MATRIX *A) {
432 for (i = 0; i < B->n; i++) {
433 for (j = 0; j < B->m; j++) {
438 if (strcmp(mode,
"cor") == 0) {
439 for (i = 0; i < Ncols; i++) {
440 for (j = 0; j < Nrows; j++) {
441 B->a[i][i + j * Ncols + addRowsBefore] = A->a[i][j];
444 }
else if (strcmp(mode,
"bpm") == 0) {
445 for (i = 0; i < Nrows; i++) {
446 for (j = 0; j < Ncols; j++) {
447 B->a[i][i * Ncols + j + addRowsBefore] = A->a[j][i];
451 for (i = 0; i < addRowsAfter; i++) {
452 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)