97 {
98 int iArg;
99 char **column, **excludeColumn, *withOnly;
100 long columns, excludeColumns;
101 char *input, *output, buffer[16384];
102 SCANNED_ARG *scanned;
104 long i, count, readCode, rankOrder;
105 int64_t rows;
106 int32_t outlierStDevPasses;
107 double **data, correlation, outlierStDevLimit;
108 double **rank;
109 short **accept;
110 unsigned long pipeFlags, dummyFlags, majorOrderFlag;
111 int32_t startShift, endShift, deltaShift;
112 long outputRows, iWith, outputRow, shiftAmount, verbose;
113 short columnMajorOrder = -1;
114
116 argc =
scanargs(&scanned, argc, argv);
117 if (argc < 2)
119
120 output = input = withOnly = NULL;
121 columns = excludeColumns = 0;
122 column = excludeColumn = NULL;
123 pipeFlags = 0;
124 rankOrder = 0;
125 outlierStDevPasses = 0;
126 outlierStDevLimit = 1.0;
127 rank = NULL;
128 accept = NULL;
129 startShift = -(endShift = 10);
130 deltaShift = 1;
131 verbose = 0;
132
133 for (iArg = 1; iArg < argc; iArg++) {
134 if (scanned[iArg].arg_type == OPTION) {
135
136 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
137 case SET_MAJOR_ORDER:
138 majorOrderFlag = 0;
139 scanned[iArg].n_items--;
140 if (scanned[iArg].n_items > 0 &&
141 (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
142 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
143 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
144 SDDS_Bomb(
"invalid -majorOrder syntax/values");
145 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
146 columnMajorOrder = 1;
147 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
148 columnMajorOrder = 0;
149 break;
150 case SET_COLUMNS:
151 if (columns)
152 SDDS_Bomb(
"only one -columns option may be given");
153 if (scanned[iArg].n_items < 2)
155 column =
tmalloc(
sizeof(*column) * (columns = scanned[iArg].n_items - 1));
156 for (i = 0; i < columns; i++)
157 column[i] = scanned[iArg].list[i + 1];
158 break;
159 case SET_EXCLUDE:
160 if (scanned[iArg].n_items < 2)
161 SDDS_Bomb(
"invalid -excludeColumns syntax");
162 moveToStringArray(&excludeColumn, &excludeColumns, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
163 break;
164 case SET_WITH:
165 if (withOnly)
166 SDDS_Bomb(
"only one -withOnly option may be given");
167 if (scanned[iArg].n_items < 2)
169 withOnly = scanned[iArg].list[1];
170 break;
171 case SET_PIPE:
172 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
174 break;
175 case SET_RANKORDER:
176 rankOrder = 1;
177 break;
178 case SET_STDEVOUTLIER:
179 scanned[iArg].n_items--;
180 outlierStDevPasses = 1;
181 outlierStDevLimit = 1.0;
182 if (!
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
184 "passes",
SDDS_LONG, &outlierStDevPasses, 1, 0, NULL) ||
185 outlierStDevPasses <= 0 || outlierStDevLimit <= 0.0)
186 SDDS_Bomb(
"invalid -stdevOutlier syntax/values");
187 break;
188 case SET_SCAN:
189 scanned[iArg].n_items--;
190 if (!
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
193 "delta",
SDDS_LONG, &deltaShift, 1, 0, NULL) ||
194 startShift >= endShift || deltaShift <= 0 || (endShift - startShift) < deltaShift)
195 SDDS_Bomb(
"invalid -scan syntax/values");
196 break;
197 case SET_VERBOSE:
198 verbose = 1;
199 break;
200 default:
201 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
202 exit(1);
203 break;
204 }
205 } else {
206 if (!input)
207 input = scanned[iArg].list[0];
208 else if (!output)
209 output = scanned[iArg].list[0];
210 else
212 }
213 }
214
216
219
220 if (!columns)
221 columns = appendToStringArray(&column, columns, "*");
222 if (withOnly)
223 columns = appendToStringArray(&column, columns, withOnly);
224
225 if ((columns = expandColumnPairNames(&SDDSin, &column, NULL, columns, excludeColumn, excludeColumns, FIND_NUMERIC_TYPE, 0)) <= 0) {
227 SDDS_Bomb(
"no columns selected for correlation analysis");
228 }
229 if (columnMajorOrder == -1)
230 columnMajorOrder = SDDSin.layout.data_mode.column_major;
231
232 setupOutputFile(&SDDSout, output, column, columns, columnMajorOrder);
233
234 if (!(data = (double **)malloc(sizeof(*data) * columns)) ||
235 (rankOrder && !(rank = (double **)malloc(sizeof(*rank) * columns))) ||
236 !(accept = (short **)malloc(sizeof(*accept) * columns)))
238 outputRows = (endShift - startShift) / deltaShift;
239 iWith = -1;
242 continue;
245 for (i = 0; i < columns; i++) {
246 if (strcmp(withOnly, column[i]) == 0)
247 iWith = i;
250 if (rankOrder)
251 rank[i] = findRank(data[i], rows);
252 if (outlierStDevPasses) {
253 if (!(accept[i] = (short *)malloc(sizeof(**accept) * rows)))
255 markStDevOutliers(data[i], outlierStDevLimit, outlierStDevPasses, accept[i], rows);
256 } else
257 accept[i] = NULL;
258 }
259 if (iWith < 0)
261 outputRow = 0;
262 for (shiftAmount = startShift; shiftAmount <= endShift; shiftAmount += deltaShift) {
263 if (verbose)
264 fprintf(stderr, "Working on shift of %ld\n", shiftAmount);
265 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, outputRow,
"ShiftAmount", shiftAmount, NULL))
267 for (i = 0; i < columns; i++) {
269 rankOrder ? rank[i] : data[i],
270 rankOrder ? rank[iWith] : data[iWith],
271 accept[i],
272 accept[iWith],
273 rows,
274 &count,
275 shiftAmount);
276 sprintf(buffer, "%sShiftedCor", column[i]);
277 if (!
SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, outputRow, buffer, correlation, NULL))
279 }
280 outputRow++;
281 }
282 for (i = 0; i < columns; i++) {
283 free(data[i]);
284 if (rankOrder)
285 free(rank[i]);
286 if (accept[i])
287 free(accept[i]);
288 }
291 }
294 return 1;
295 }
298 return 1;
299 }
300
301 return 0;
302}
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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.
#define SDDS_LONG
Identifier for the signed 32-bit integer data 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 shiftedLinearCorrelationCoefficient(double *data1, double *data2, short *accept1, short *accept2, long rows, long *count, long shift)
Compute the linear correlation coefficient between two data sets with a given shift.
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.