SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
elegant2genesis.c
Go to the documentation of this file.
1/**
2 * @file elegant2genesis.c
3 * @brief Converts the output file from Elegant into the beamline file format used by Genesis.
4 *
5 * @section Introduction
6 * This program processes beam data generated by Elegant, applies various transformations
7 * and filters, and outputs the result in a format compatible with Genesis. Features include
8 * momentum tail removal, steering beam centroids, and customizable slicing based on specified
9 * wavelengths or slices.
10 *
11 * @section Usage
12 * ```
13 * elegant2genesis [<input>] [<output>]
14 * [-pipe=[in][,out]]
15 * [-textOutput]
16 * [-totalCharge=<charge-in-Coulombs>]
17 * [-chargeParameter=<name>]
18 * [-wavelength=<meters>]
19 * [-slices=<integer>]
20 * [-steer]
21 * [-removePTails=deltaLimit=<value>[,fit][,beamOutput=<filename>]]
22 * [-reverseOrder]
23 * [-localFit]
24 * ```
25 *
26 * @section Options
27 * | Option | Description |
28 * |----------------------------------------|-----------------------------------------------------------------------------|
29 * | `-pipe` | Set up pipe communication for input and/or output. |
30 * | `-textOutput` | Make the output file a text file instead of an SDDS file. |
31 * | `-totalCharge` | Specify the total charge in Coulombs. |
32 * | `-chargeParameter` | Specify the name of a parameter in the input file that gives the total charge. |
33 * | `-wavelength` | Specify the wavelength of light in meters. |
34 * | `-slices` | Specify the number of slices to divide the beam into. |
35 * | `-steer` | Force the x, x', y, and y' centroids for the whole beam to zero. |
36 * | `-removePTails` | Remove the momentum tails from the beam |
37 * | `-reverseOrder` | Output the data for the tail of the beam first instead of the head. |
38 * | `-localFit` | Perform a local linear fit of momentum vs time for each slice, removing a contribution to the energy spread. |
39 *
40 * @section IC Incompatible Options
41 * The following options are mutually exclusive:
42 * - `-wavelength` and `-slices` cannot be used together.
43 *
44 * @section DD Detailed Description
45 * This program reads beam data from an Elegant output file, processes it according to the specified options,
46 * and generates an output file in the Genesis-compatible beamline format. The processing includes:
47 * - **Momentum Tail Removal:** Using the `-removePTails` option to eliminate particles with momentum deviations beyond a specified limit.
48 * - **Steering Centroids:** Adjusting the centroids of the beam to zero using the `-steer` option.
49 * - **Slicing:** Dividing the beam into slices based on wavelength or a specified number of slices.
50 * - **Local Linear Fit:** Applying a local linear fit to momentum vs time data for each slice with the `-localFit` option.
51 *
52 * @copyright
53 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
54 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
55 *
56 * @license
57 * This file is distributed under the terms of the Software License Agreement
58 * found in the file LICENSE included with this distribution.
59 *
60 * @authors
61 * R. Soliday, M. Borland
62 */
63
64#include "mdb.h"
65#include "SDDS.h"
66#include "scan.h"
67
68/* Enumeration for option types */
69enum option_type {
70 SET_WAVELENGTH,
71 SET_SLICES,
72 SET_TOTALCHARGE,
73 SET_TEXTOUTPUT,
74 SET_STEER,
75 SET_CHARGEPARAMETER,
76 SET_PIPE,
77 SET_REMPTAILS,
78 SET_REVERSEORDER,
79 SET_LOCAL_FIT,
80 N_OPTIONS
81};
82
83char *option[N_OPTIONS] = {
84 "wavelength",
85 "slices",
86 "totalcharge",
87 "textoutput",
88 "steer",
89 "chargeparameter",
90 "pipe",
91 "removePTails",
92 "reverseorder",
93 "localfit"};
94
95char *USAGE =
96 "Usage:\n"
97 " elegant2genesis [<input>] [<output>]\n"
98 " [-pipe=[in][,out]] \n"
99 " [-textOutput]\n"
100 " [-totalCharge=<charge-in-Coulombs>]\n"
101 " [-chargeParameter=<name>]\n"
102 " [-wavelength=<meters>]\n"
103 " [-slices=<integer>]\n"
104 " [-steer] \n"
105 " [-removePTails=deltaLimit=<value>[,fit][,beamOutput=<filename>]]\n"
106 " [-reverseOrder] \n"
107 " [-localFit]\n"
108 "Options:\n"
109 " -pipe=[in][,out] Set up pipe communication for input and/or output.\n"
110 " -textOutput Make the output file a text file instead of an SDDS file.\n"
111 " -totalCharge=<charge-in-Coulombs> Specify the total charge in Coulombs.\n"
112 " -chargeParameter=<name> Specify the name of a parameter in the input file that gives the total charge in Coulombs.\n"
113 " -wavelength=<meters> Specify the wavelength of light in meters.\n"
114 " -slices=<integer> Specify the number of slices to divide the beam into.\n"
115 " -steer Force the x, x', y, and y' centroids for the whole beam to zero.\n"
116 " Slices may still have nonzero centroids.\n"
117 " -removePTails=deltaLimit=<value>[,fit][,beamOutput=<filename>]\n"
118 " Remove the momentum tails from the beam.\n"
119 " deltaLimit specifies the maximum |p - <p>|/<p> to keep.\n"
120 " 'fit' enables a linear fit to (t, p) for tail removal based on residuals.\n"
121 " 'beamOutput' writes the filtered beam to the specified file for review.\n"
122 " -reverseOrder Output the data for the tail of the beam first instead of the head.\n"
123 " -localFit Perform a local linear fit of momentum vs time for each slice and subtract it from the momentum data,\n"
124 " removing a contribution to the energy spread.\n\n"
125 "Program by Robert Soliday and Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
126
127#define PTAILS_DELTALIMIT 0x0001U
128#define PTAILS_FITMODE 0x0002U
129#define PTAILS_OUTPUT 0x0004U
130
131int64_t removeMomentumTails(double *x, double *xp, double *y, double *yp, double *s, double *p, double *t, int64_t rows, double limit, unsigned long flags);
132void removeLocalFit(double *p, double *s, short *selected, double pAverage, int64_t rows);
133
134/* ********** */
135
136int main(int argc, char **argv) {
137 SDDS_DATASET SDDS_input, SDDS_output, SDDS_pTails;
138 FILE *fileID = NULL;
139 SCANNED_ARG *s_arg;
140 long i_arg;
141 char *input, *output;
142 unsigned long pipeFlags = 0;
143 long noWarnings = 0, tmpfile_used = 0;
144 long retval, sddsOutput = 1, steer = 0, firstOne, sliceOffset = 0;
145 int64_t i, j, rows, origRows;
146 long reverseOrder = 0;
147 char *chargeParameter;
148 unsigned long removePTailsFlags = 0;
149 double pTailsDeltaLimit, term;
150 char *pTailsOutputFile = NULL;
151 long localFit = 0;
152 short *selected;
153
154 char column[7][15] = {"x", "xp", "y", "yp", "t", "p", "particleID"};
155 long columnIndex[7];
156
157 double *tValues, *sValues, *xValues, *xpValues, *yValues, *ypValues, *pValues;
158 double sAverage, pAverage, pStDev;
159 double xAverage, xpAverage, xRMS, x2Average, xp2Average, xxpAverage, xEmittance;
160 double yAverage, ypAverage, yRMS, y2Average, yp2Average, yypAverage, yEmittance;
161 double sMin = 1, sMax = -1, s1, s2;
162 /*
163 double pMin, pMax;
164 */
165 double alphax, alphay;
166
167 double wavelength = 0.0001;
168 double totalCharge = 0;
169 double current;
170 long slices = 4;
171 long tmp = 0;
172 long N = 0;
173 double Ne = 0;
174
175 input = output = NULL;
176 sValues = NULL;
177 chargeParameter = NULL;
178 selected = NULL;
179
181 argc = scanargs(&s_arg, argc, argv);
182 if (argc < 3) {
183 fprintf(stderr, "Error: Insufficient arguments.\n");
184 fprintf(stderr, "%s", USAGE);
185 exit(EXIT_FAILURE);
186 }
187
188 /* Parse the command line */
189 for (i_arg = 1; i_arg < argc; i_arg++) {
190 if (s_arg[i_arg].arg_type == OPTION) {
191 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
192 case SET_TOTALCHARGE:
193 if (s_arg[i_arg].n_items != 2) {
194 fprintf(stderr, "Error: Invalid -totalCharge syntax.\n");
195 exit(EXIT_FAILURE);
196 }
197 if (sscanf(s_arg[i_arg].list[1], "%lf", &totalCharge) != 1) {
198 fprintf(stderr, "Error: Invalid -totalCharge value.\n");
199 exit(EXIT_FAILURE);
200 }
201 break;
202 case SET_WAVELENGTH:
203 if (tmp == 2) {
204 fprintf(stderr, "Error: -wavelength and -slices cannot be used together.\n");
205 exit(EXIT_FAILURE);
206 }
207 if (s_arg[i_arg].n_items != 2) {
208 fprintf(stderr, "Error: Invalid -wavelength syntax.\n");
209 exit(EXIT_FAILURE);
210 }
211 if (sscanf(s_arg[i_arg].list[1], "%lf", &wavelength) != 1 || wavelength <= 0) {
212 fprintf(stderr, "Error: Invalid -wavelength value.\n");
213 exit(EXIT_FAILURE);
214 }
215 tmp = 1;
216 break;
217 case SET_SLICES:
218 if (tmp == 1) {
219 fprintf(stderr, "Error: -wavelength and -slices cannot be used together.\n");
220 exit(EXIT_FAILURE);
221 }
222 if (s_arg[i_arg].n_items != 2) {
223 fprintf(stderr, "Error: Invalid -slices syntax.\n");
224 exit(EXIT_FAILURE);
225 }
226 if (sscanf(s_arg[i_arg].list[1], "%ld", &slices) != 1 || slices <= 0) {
227 fprintf(stderr, "Error: Invalid -slices value.\n");
228 exit(EXIT_FAILURE);
229 }
230 tmp = 2;
231 break;
232 case SET_TEXTOUTPUT:
233 sddsOutput = 0;
234 break;
235 case SET_STEER:
236 steer = 1;
237 break;
238 case SET_CHARGEPARAMETER:
239 if (s_arg[i_arg].n_items != 2) {
240 fprintf(stderr, "Error: Invalid -chargeParameter syntax.\n");
241 exit(EXIT_FAILURE);
242 }
243 chargeParameter = s_arg[i_arg].list[1];
244 break;
245 case SET_PIPE:
246 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
247 SDDS_Bomb("Invalid -pipe syntax.");
248 }
249 break;
250 case SET_REMPTAILS:
251 if (s_arg[i_arg].n_items > 1) {
252 if (!scanItemList(&removePTailsFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
253 "deltalimit", SDDS_DOUBLE, &pTailsDeltaLimit, 1, PTAILS_DELTALIMIT,
254 "fit", -1, NULL, 0, PTAILS_FITMODE,
255 "beamoutput", SDDS_STRING, &pTailsOutputFile, 1, PTAILS_OUTPUT,
256 NULL) ||
257 !(removePTailsFlags & PTAILS_DELTALIMIT) || pTailsDeltaLimit <= 0) {
258 SDDS_Bomb("Invalid -removePTails syntax or values.");
259 }
260 }
261 break;
262 case SET_REVERSEORDER:
263 reverseOrder = 1;
264 break;
265 case SET_LOCAL_FIT:
266 localFit = 1;
267 break;
268 default:
269 fprintf(stderr, "Error: Unknown option '%s'.\n", s_arg[i_arg].list[0]);
270 exit(EXIT_FAILURE);
271 }
272 } else {
273 if (input == NULL) {
274 input = s_arg[i_arg].list[0];
275 } else if (output == NULL) {
276 output = s_arg[i_arg].list[0];
277 } else {
278 fprintf(stderr, "Error: Too many filenames provided.\n");
279 exit(EXIT_FAILURE);
280 }
281 }
282 }
283
284 processFilenames("elegant2genesis", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
285
286 /* Open the input file */
287 if (!SDDS_InitializeInput(&SDDS_input, input)) {
288 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
289 exit(EXIT_FAILURE);
290 }
291
292 /* Check for needed columns */
293 for (i = 0; i < 7; i++) {
294 if ((columnIndex[i] = SDDS_GetColumnIndex(&SDDS_input, column[i])) < 0) {
295 fprintf(stderr, "Error: Column '%s' does not exist.\n", column[i]);
296 exit(EXIT_FAILURE);
297 }
298 }
299
300 if (removePTailsFlags & PTAILS_OUTPUT) {
301 if (!SDDS_InitializeOutput(&SDDS_pTails, SDDS_BINARY, 0, NULL, NULL, pTailsOutputFile) ||
302 !SDDS_DefineSimpleColumn(&SDDS_pTails, "t", "s", SDDS_DOUBLE) ||
303 !SDDS_DefineSimpleColumn(&SDDS_pTails, "p", NULL, SDDS_DOUBLE) ||
304 !SDDS_DefineSimpleColumn(&SDDS_pTails, "x", "m", SDDS_DOUBLE) ||
305 !SDDS_DefineSimpleColumn(&SDDS_pTails, "xp", NULL, SDDS_DOUBLE) ||
306 !SDDS_DefineSimpleColumn(&SDDS_pTails, "y", "m", SDDS_DOUBLE) ||
307 !SDDS_DefineSimpleColumn(&SDDS_pTails, "yp", NULL, SDDS_DOUBLE) ||
308 !SDDS_WriteLayout(&SDDS_pTails)) {
309 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
310 exit(EXIT_FAILURE);
311 }
312 }
313
314 retval = -1;
315 firstOne = 1;
316 while ((retval = SDDS_ReadPage(&SDDS_input)) >= 1) {
317 rows = origRows = SDDS_RowCount(&SDDS_input);
318 if (rows < 1) {
319 fprintf(stderr, "Error: No rows found for page %ld.\n", retval);
320 exit(EXIT_FAILURE);
321 }
322 /* Get all the needed column data */
323 tValues = SDDS_GetNumericColumn(&SDDS_input, "t", SDDS_DOUBLE);
324 xValues = SDDS_GetNumericColumn(&SDDS_input, "x", SDDS_DOUBLE);
325 xpValues = SDDS_GetNumericColumn(&SDDS_input, "xp", SDDS_DOUBLE);
326 yValues = SDDS_GetNumericColumn(&SDDS_input, "y", SDDS_DOUBLE);
327 ypValues = SDDS_GetNumericColumn(&SDDS_input, "yp", SDDS_DOUBLE);
328 pValues = SDDS_GetNumericColumn(&SDDS_input, "p", SDDS_DOUBLE);
329
330 if (chargeParameter && !SDDS_GetParameterAsDouble(&SDDS_input, chargeParameter, &totalCharge)) {
331 SDDS_Bomb("Unable to read charge from file.");
332 }
333 if (!(tValues && xValues && xpValues && yValues && ypValues && pValues)) {
334 fprintf(stderr, "Error: Invalid data for page %ld.\n", retval);
335 exit(EXIT_FAILURE);
336 }
337 selected = realloc(selected, sizeof(*selected) * rows);
338 sValues = realloc(sValues, sizeof(*sValues) * rows);
339 if (!selected || !sValues) {
340 SDDS_Bomb("Memory allocation failure.");
341 }
342
343 sAverage = xAverage = xpAverage = yAverage = ypAverage = 0;
344 for (i = 0; i < rows; i++) { /* Calculate s values and sAverage */
345 sValues[i] = tValues[i] * 2.99792458e8;
346 sAverage += tValues[i];
347 xAverage += xValues[i];
348 xpAverage += xpValues[i];
349 yAverage += yValues[i];
350 ypAverage += ypValues[i];
351 }
352 sAverage = sAverage * 2.99792458e8 / rows;
353 xAverage /= rows;
354 xpAverage /= rows;
355 yAverage /= rows;
356 ypAverage /= rows;
357
358 for (i = 0; i < rows; i++) {
359 /* Move origin of s values to center at sAverage and flip the sign */
360 sValues[i] = sAverage - sValues[i];
361 }
362
363 /* Remove the momentum tails, if requested */
364 if (removePTailsFlags) {
365 rows = removeMomentumTails(xValues, xpValues, yValues, ypValues, sValues, pValues, tValues, rows, pTailsDeltaLimit, removePTailsFlags);
366 if (rows == 0) {
367 SDDS_Bomb("All data removed by P-tails filter.");
368 }
369 if (removePTailsFlags & PTAILS_OUTPUT) {
370 if (!SDDS_StartPage(&SDDS_pTails, rows) ||
371 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, xValues, rows, "x") ||
372 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, xpValues, rows, "xp") ||
373 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, yValues, rows, "y") ||
374 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, ypValues, rows, "yp") ||
375 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, tValues, rows, "t") ||
376 !SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, pValues, rows, "p") ||
377 !SDDS_WritePage(&SDDS_pTails)) {
378 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
379 exit(EXIT_FAILURE);
380 }
381 }
382 }
383
384 if (steer) {
385 /* Set the centroids for the whole beam to zero */
386 for (i = 0; i < rows; i++) {
387 xValues[i] -= xAverage;
388 xpValues[i] -= xpAverage;
389 yValues[i] -= yAverage;
390 ypValues[i] -= ypAverage;
391 }
392 }
393
394 /* Find limits of distribution in s */
395 find_min_max(&sMin, &sMax, sValues, rows);
396 if ((tmp == 1) || (tmp == 0)) { /* Calculate the number of slices from the wavelength */
397 slices = (sMax - sMin) / wavelength + 1;
398 }
399 if (tmp == 2) { /* Calculate the wavelength from the number of slices */
400 wavelength = (sMax - sMin) / slices;
401 }
402
403 if (firstOne) {
404 /* Open the output file */
405 if (sddsOutput) {
406 if (!SDDS_InitializeOutput(&SDDS_output, SDDS_ASCII, 1, NULL, NULL, output)) {
407 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
408 exit(EXIT_FAILURE);
409 }
410 if ((SDDS_DefineColumn(&SDDS_output, "s", "Location", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
411 (SDDS_DefineColumn(&SDDS_output, "t", "Time position", "s", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
412 (SDDS_DefineColumn(&SDDS_output, "gamma", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
413 (SDDS_DefineColumn(&SDDS_output, "dgamma", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
414 (SDDS_DefineColumn(&SDDS_output, "Sdelta", NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
415 (SDDS_DefineColumn(&SDDS_output, "xemit", "NormalizedEmittance-x", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
416 (SDDS_DefineColumn(&SDDS_output, "yemit", "NormalizedEmittance-y", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
417 (SDDS_DefineColumn(&SDDS_output, "xrms", "Beam Size-x", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
418 (SDDS_DefineColumn(&SDDS_output, "yrms", "Beam Size-y", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
419 (SDDS_DefineColumn(&SDDS_output, "xavg", "Position-x", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
420 (SDDS_DefineColumn(&SDDS_output, "yavg", "Position-y", "m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
421 (SDDS_DefineColumn(&SDDS_output, "pxavg", "Average x'", "rad", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
422 (SDDS_DefineColumn(&SDDS_output, "pyavg", "Average y'", "rad", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
423 (SDDS_DefineColumn(&SDDS_output, "alphax", "Alpha-x", NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
424 (SDDS_DefineColumn(&SDDS_output, "alphay", "Alpha-y", NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
425 (SDDS_DefineColumn(&SDDS_output, "current", "Current", "Amp", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
426 (SDDS_DefineColumn(&SDDS_output, "wakez", "Wake Loss", "eV/m", NULL, NULL, SDDS_DOUBLE, 0) == -1) ||
427 (SDDS_DefineColumn(&SDDS_output, "N", "Number of macroparticles", NULL, NULL, NULL, SDDS_LONG, 0) == -1) ||
428 (SDDS_DefineColumn(&SDDS_output, "Ne", "Number of electrons", NULL, NULL, NULL, SDDS_DOUBLE, 0) == -1)) {
429 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
430 exit(EXIT_FAILURE);
431 }
432 if ((SDDS_WriteLayout(&SDDS_output) != 1) || (SDDS_StartPage(&SDDS_output, slices) != 1)) {
433 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
434 exit(EXIT_FAILURE);
435 }
436 } else {
437 fileID = fopen(output, "w");
438 if (fileID == NULL) {
439 fprintf(stderr, "Error: Unable to open output file for writing.\n");
440 exit(EXIT_FAILURE);
441 }
442 fprintf(fileID, "%ld", slices);
443 }
444 firstOne = 0;
445 } else {
446 if (sddsOutput && !SDDS_LengthenTable(&SDDS_output, slices)) {
447 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
448 exit(EXIT_FAILURE);
449 }
450 sliceOffset += slices;
451 }
452
453 /* For each slice, calculate all the needed values */
454 for (i = 0; i < slices; i++) {
455 N = 0;
456 xAverage = xpAverage = xRMS = x2Average = xp2Average = xxpAverage = 0;
457 yAverage = ypAverage = yRMS = y2Average = yp2Average = yypAverage = 0;
458 pAverage = alphax = alphay = 0;
459
460 if (!reverseOrder) {
461 s1 = sMin + (wavelength * i);
462 s2 = sMin + (wavelength * (i + 1));
463 } else {
464 s1 = sMin + (wavelength * (slices - i - 1));
465 s2 = sMin + (wavelength * (slices - i));
466 }
467
468 for (j = 0; j < rows; j++) {
469 selected[j] = 0;
470 if ((s1 <= sValues[j]) && (s2 > sValues[j])) {
471 selected[j] = 1;
472 N++;
473 xAverage += xValues[j];
474 xpAverage += xpValues[j];
475 yAverage += yValues[j];
476 ypAverage += ypValues[j];
477 pAverage += pValues[j];
478 }
479 }
480
481 if (N > 2) {
482 current = N * 2.99792458e8 * (totalCharge / (origRows * wavelength));
483 Ne = totalCharge * N / (e_mks * origRows);
484 xAverage /= N;
485 yAverage /= N;
486 xpAverage /= N;
487 ypAverage /= N;
488 pAverage /= N;
489
490 pStDev = 0;
491 if (localFit) {
492 removeLocalFit(pValues, sValues, selected, pAverage, rows);
493 }
494 for (j = 0; j < rows; j++) {
495 if (selected[j]) {
496 pStDev += (pValues[j] - pAverage) * (pValues[j] - pAverage);
497 x2Average += (xValues[j] - xAverage) * (xValues[j] - xAverage);
498 y2Average += (yValues[j] - yAverage) * (yValues[j] - yAverage);
499 xp2Average += (xpValues[j] - xpAverage) * (xpValues[j] - xpAverage);
500 yp2Average += (ypValues[j] - ypAverage) * (ypValues[j] - ypAverage);
501 xxpAverage += (xValues[j] - xAverage) * (xpValues[j] - xpAverage);
502 yypAverage += (yValues[j] - yAverage) * (ypValues[j] - ypAverage);
503 }
504 }
505 pStDev = sqrt(pStDev / (N - 1.0));
506 x2Average /= N;
507 y2Average /= N;
508 xp2Average /= N;
509 yp2Average /= N;
510 xxpAverage /= N;
511 yypAverage /= N;
512 xRMS = sqrt(x2Average);
513 yRMS = sqrt(y2Average);
514
515 if ((term = (x2Average * xp2Average) - (xxpAverage * xxpAverage)) > 0) {
516 xEmittance = sqrt(term) * pAverage;
517 } else {
518 xEmittance = 0;
519 }
520
521 if ((term = (y2Average * yp2Average) - (yypAverage * yypAverage)) > 0) {
522 yEmittance = sqrt(term) * pAverage;
523 } else {
524 yEmittance = 0;
525 }
526
527 alphax = -xxpAverage / ((xEmittance > 0) ? (xEmittance / pAverage) : 1);
528 alphay = -yypAverage / ((yEmittance > 0) ? (yEmittance / pAverage) : 1);
529 } else {
530 pAverage = pStDev = xEmittance = yEmittance = xRMS = yRMS = xAverage = yAverage = xpAverage = ypAverage = alphax = alphay = current = Ne = 0;
531 }
532
533 if (sddsOutput) {
534 if (SDDS_SetRowValues(&SDDS_output, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, i + sliceOffset,
535 "s", s1,
536 "t", -s1 / c_mks,
537 "gamma", pAverage,
538 "dgamma", pStDev,
539 "Sdelta", (pAverage > 0) ? (pStDev / pAverage) : 0,
540 "xemit", xEmittance,
541 "yemit", yEmittance,
542 "xrms", xRMS,
543 "yrms", yRMS,
544 "xavg", xAverage,
545 "yavg", yAverage,
546 "pxavg", xpAverage,
547 "pyavg", ypAverage,
548 "alphax", alphax,
549 "alphay", alphay,
550 "current", current,
551 "wakez", 0.0,
552 "N", N,
553 "Ne", Ne,
554 NULL) != 1) {
555 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
556 exit(EXIT_FAILURE);
557 }
558 } else {
559 fprintf(fileID, "\n%.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E %.6E 0.000000E+00",
560 s1, pAverage, pStDev, xEmittance, yEmittance, xRMS, yRMS,
561 xAverage, yAverage, xpAverage, ypAverage, alphax, alphay, current);
562 }
563 }
564
565 free(tValues);
566 free(xValues);
567 free(xpValues);
568 free(yValues);
569 free(ypValues);
570 free(pValues);
571 }
572 free(sValues);
573
574 /* Close the output file */
575 if (sddsOutput) {
576 if (!SDDS_WritePage(&SDDS_output)) {
577 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
578 exit(EXIT_FAILURE);
579 }
580 if (!SDDS_Terminate(&SDDS_output)) {
581 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
582 exit(EXIT_FAILURE);
583 }
584 } else {
585 fclose(fileID);
586 }
587
588 /* Close the input file */
589 if (!SDDS_Terminate(&SDDS_input)) {
590 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
591 exit(EXIT_FAILURE);
592 }
593 if ((removePTailsFlags & PTAILS_OUTPUT) && !SDDS_Terminate(&SDDS_pTails)) {
594 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
595 exit(EXIT_FAILURE);
596 }
597
598 return EXIT_SUCCESS;
599}
600
601int64_t removeMomentumTails(double *x, double *xp, double *y, double *yp, double *s, double *p, double *t, int64_t rows, double limit, unsigned long flags) {
602 double *delta, pAve;
603 int64_t ip, jp;
604
605#if defined(DEBUG)
606 static FILE *fp = NULL;
607#endif
608
609 if (rows == 0)
610 return rows;
611
612 delta = malloc(sizeof(*delta) * rows);
613 if (!delta)
614 SDDS_Bomb("Memory allocation failure.");
615
616 for (ip = pAve = 0; ip < rows; ip++)
617 pAve += p[ip];
618 pAve /= rows;
619
620 for (ip = 0; ip < rows; ip++)
621 delta[ip] = (p[ip] - pAve) / pAve;
622
623 if (flags & PTAILS_FITMODE) {
624 double slope, intercept, variance;
625 if (!unweightedLinearFit(s, delta, rows, &slope, &intercept, &variance))
626 SDDS_Bomb("Fit failed in momentum tail removal.");
627 for (ip = 0; ip < rows; ip++)
628 delta[ip] -= s[ip] * slope + intercept;
629 }
630
631 jp = rows - 1;
632 for (ip = 0; ip < rows; ip++) {
633 if (fabs(delta[ip]) > limit) {
634 if (jp > ip) {
635 x[ip] = x[jp];
636 xp[ip] = xp[jp];
637 y[ip] = y[jp];
638 yp[ip] = yp[jp];
639 s[ip] = s[jp];
640 p[ip] = p[jp];
641 t[ip] = t[jp];
642 delta[ip] = delta[jp];
643 jp--;
644 ip--;
645 }
646 rows--;
647 }
648 }
649 free(delta);
650
651#if defined(DEBUG)
652 if (!fp) {
653 fp = fopen("e2g.sdds", "w");
654 if (fp) {
655 fprintf(fp, "SDDS1\n&column name=x type=double &end\n");
656 fprintf(fp, "&column name=xp type=double &end\n");
657 fprintf(fp, "&column name=y type=double &end\n");
658 fprintf(fp, "&column name=yp type=double &end\n");
659 fprintf(fp, "&column name=s type=double &end\n");
660 fprintf(fp, "&column name=p type=double &end\n");
661 fprintf(fp, "&data mode=ascii &end\n");
662 fprintf(fp, "%ld\n", rows);
663 }
664 }
665 if (fp) {
666 for (ip = 0; ip < rows; ip++)
667 fprintf(fp, "%le %le %le %le %le %le\n", x[ip], xp[ip], y[ip], yp[ip], s[ip], p[ip]);
668 }
669#endif
670
671 return rows;
672}
673
674void removeLocalFit(double *p, double *s, short *selected, double pAverage, int64_t rows) {
675 double slope, intercept, variance;
676 int64_t i;
677
678 if (unweightedLinearFitSelect(s, p, selected, rows, &slope, &intercept, &variance)) {
679 for (i = 0; i < rows; i++) {
680 if (selected[i])
681 p[i] -= intercept + slope * s[i] - pAverage;
682 }
683 }
684}
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_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_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.
void * SDDS_GetNumericColumn(SDDS_DATASET *SDDS_dataset, char *column_name, int32_t desiredType)
Retrieves the data of a specified numerical column as an array of a desired numerical type,...
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.c:33
long unweightedLinearFitSelect(double *xData, double *yData, short *select, long nData, double *slope, double *intercept, double *variance)
Performs an unweighted linear fit on the provided data with optional data point selection.
Definition linfit.c:60
long unweightedLinearFit(double *xData, double *yData, long nData, double *slope, double *intercept, double *variance)
Performs an unweighted linear fit on the provided data.
Definition linfit.c:37
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
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.