88#define SET_WAVELENGTH 0
90#define SET_TOTALCHARGE 2
91#define SET_TEXTOUTPUT 3
93#define SET_CHARGEPARAMETER 5
95#define SET_REMPTAILS 7
96#define SET_REVERSEORDER 8
97#define SET_LOCAL_FIT 9
100char *option[N_OPTIONS] = {
"wavelength",
"slices",
"totalcharge",
"textoutput",
"steer",
101 "chargeparameter",
"pipe",
"removePTails",
102 "reverseorder",
"localfit"};
104char *USAGE =
"elegant2genesis [<input>] [<output>] [-pipe=[in][,out]] [-textOutput]\n\
105[-totalCharge=<charge-in-Coulombs> | -chargeParameter=<name>]\n\
106[-wavelength=<meters> | -slices=<integer>]\n\
107[-steer] [-removePTails=deltaLimit=<value>[,fit][,beamOutput=<filename>]]\n\
108[-reverseOrder] [-localFit]\n\n\
109textOutput Make the output file a text file instead of an SDDS file.\n\
110totalCharge Specify the total charge in Coulombs.\n\
111chargeParameter Specify the name of a parameter in the input file that gives\n\
112 the total charge in Coulombs.\n\
113wavelength Specify the wavelength of light in meters.\n\
114slices Specify the number of slices to cut the beam into.\n\
115steer Force the x, x', y, and y' centroids for the whole beam to zero.\n\
116 Slices may still have nonzero centroids.\n\
117removePTail Removes the momentum tails from the beam. deltaLimit is the maximum\n\
118 |p-<p>|/<p> that will be kept. If 'fit' is given, then a linear fit to\n\
119 (t, p) is done and removal is based on residuals from this fit.\n\
120 If 'beamOutput' is given, the filtered beam is written to the named\n\
122reverseOrder By default, the data for the head of the beam comes first. This\n\
123 option causes elegant to put the data for the tail of the beam \n\
125localFit If given, then for each slice the program performs a local linear\n\
126 fit of momentum vs time, and subtracts it from the momentum data.\n\
127 This removes a contribution to the energy spread, but may not be\n\
128 appropriate if slices are longer than the cooperation length.\n\n\
129Program by Robert Soliday and Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
131#define PTAILS_DELTALIMIT 0x0001U
132#define PTAILS_FITMODE 0x0002U
133#define PTAILS_OUTPUT 0X0004U
134int64_t removeMomentumTails(
double *x,
double *xp,
double *y,
double *yp,
double *s,
double *p,
double *t, int64_t rows,
double limit,
unsigned long flags);
135void removeLocalFit(
double *p,
double *s,
short *selected,
double pAverage, int64_t rows);
139int main(
int argc,
char **argv) {
144 char *input, *output;
145 unsigned long pipeFlags = 0;
146 long noWarnings = 0, tmpfile_used = 0;
147 long retval, sddsOutput = 1, steer = 0, firstOne, sliceOffset = 0;
148 int64_t i, j, rows, origRows;
149 long reverseOrder = 0;
150 char *chargeParameter;
151 unsigned long removePTailsFlags = 0;
152 double pTailsDeltaLimit, term;
153 char *pTailsOutputFile = NULL;
157 char column[7][15] = {
"x",
"xp",
"y",
"yp",
"t",
"p",
"particleID"};
160 double *tValues, *sValues, *xValues, *xpValues, *yValues, *ypValues, *pValues;
161 double sAverage, pAverage, pStDev;
162 double xAverage, xpAverage, xRMS, x2Average, xp2Average, xxpAverage, xEmittance;
163 double yAverage, ypAverage, yRMS, y2Average, yp2Average, yypAverage, yEmittance;
164 double sMin = 1, sMax = -1, s1, s2;
168 double alphax, alphay;
170 double wavelength = 0.0001;
171 double totalCharge = 0;
178 input = output = NULL;
180 chargeParameter = NULL;
184 argc =
scanargs(&s_arg, argc, argv);
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");
197 if (sscanf(s_arg[i_arg].list[1],
"%lf", &totalCharge) != 1) {
198 fprintf(stderr,
"error: invalid -totalCharge syntax or value\n");
204 fprintf(stderr,
"error: -wavelength and -slices can not be used together\n");
207 if (s_arg[i_arg].n_items != 2) {
208 fprintf(stderr,
"error: invalid -wavelength syntax\n");
211 if (sscanf(s_arg[i_arg].list[1],
"%lf", &wavelength) != 1 || wavelength <= 0) {
212 fprintf(stderr,
"error: invalid -wavelength syntax or value\n");
219 fprintf(stderr,
"error: -wavelength and -slices can not be used together\n");
222 if (s_arg[i_arg].n_items != 2) {
223 fprintf(stderr,
"error: invalid -slices syntax\n");
226 if (sscanf(s_arg[i_arg].list[1],
"%ld", &slices) != 1 || slices <= 0) {
227 fprintf(stderr,
"error: invalid -slices syntax or value\n");
238 case SET_CHARGEPARAMETER:
239 if (s_arg[i_arg].n_items != 2) {
240 fprintf(stderr,
"error: invalid -chargeParameter syntax\n");
243 chargeParameter = s_arg[i_arg].list[1];
246 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
250 if (s_arg[i_arg].n_items -= 1) {
251 if (!
scanItemList(&removePTailsFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
252 "deltalimit",
SDDS_DOUBLE, &pTailsDeltaLimit, 1, PTAILS_DELTALIMIT,
"fit", -1, NULL, 0, PTAILS_FITMODE,
"beamoutput",
SDDS_STRING, &pTailsOutputFile, 1, PTAILS_OUTPUT, NULL) ||
253 !(removePTailsFlags & PTAILS_DELTALIMIT) || pTailsDeltaLimit <= 0)
254 SDDS_Bomb(
"invalid -removePTails syntax or values");
257 case SET_REVERSEORDER:
264 fprintf(stderr,
"error: unknown switch: %s\n", s_arg[i_arg].list[0]);
269 input = s_arg[i_arg].list[0];
270 }
else if (output == NULL) {
271 output = s_arg[i_arg].list[0];
273 fprintf(stderr,
"too many filenames\n");
279 processFilenames(
"elegant2genesis", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
288 for (i = 0; i < 7; i++) {
290 fprintf(stderr,
"error: column %s does not exist\n", column[i]);
295 if (removePTailsFlags & PTAILS_OUTPUT) {
309 rows = origRows = SDDS_RowCount(&SDDS_input);
311 fprintf(stderr,
"error: no rows found for page %ld\n", retval);
323 SDDS_Bomb(
"unable to read charge from file");
324 if ((!(tValues)) || (!(xValues)) || (!(xpValues)) || (!(yValues)) || (!(ypValues)) || (!(pValues))) {
325 fprintf(stderr,
"error: invalid data for page %ld\n", retval);
328 selected = realloc(selected,
sizeof(*selected) * rows);
329 sValues = realloc(sValues,
sizeof(*sValues) * rows);
330 sAverage = xAverage = xpAverage = yAverage = ypAverage = 0;
331 for (i = 0; i < rows; i++) {
332 sValues[i] = tValues[i] * 2.99792458e8;
333 sAverage += tValues[i];
334 xAverage += xValues[i];
335 xpAverage += xpValues[i];
336 yAverage += yValues[i];
337 ypAverage += ypValues[i];
339 sAverage = sAverage * 2.99792458e8 / rows;
345 for (i = 0; i < rows; i++)
347 sValues[i] = sAverage - sValues[i];
350 if (removePTailsFlags) {
351 if (!(rows = removeMomentumTails(xValues, xpValues, yValues, ypValues, sValues, pValues, tValues, rows, pTailsDeltaLimit, removePTailsFlags)))
352 SDDS_Bomb(
"all data removed by P-tails filter");
353 if (removePTailsFlags & PTAILS_OUTPUT) {
355 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, xValues, rows,
"x") ||
356 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, xpValues, rows,
"xp") ||
357 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, yValues, rows,
"y") ||
358 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, ypValues, rows,
"yp") ||
359 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, tValues, rows,
"t") ||
360 !
SDDS_SetColumn(&SDDS_pTails, SDDS_SET_BY_NAME, pValues, rows,
"p") ||
370 for (i = 0; i < rows; i++) {
371 xValues[i] -= xAverage;
372 xpValues[i] -= xpAverage;
373 yValues[i] -= yAverage;
374 ypValues[i] -= ypAverage;
380 if ((tmp == 1) || (tmp == 0)) {
381 slices = (sMax - sMin) / wavelength + 1;
384 wavelength = (sMax - sMin) / slices;
411 (
SDDS_DefineColumn(&SDDS_output,
"N",
"Number of macroparticles", NULL, NULL, NULL,
SDDS_LONG, 0) == -1) || (
SDDS_DefineColumn(&SDDS_output,
"Ne",
"Number of electrons", NULL, NULL, NULL,
SDDS_DOUBLE, 0) == -1)) {
420 fileID = fopen(output,
"w");
421 if (fileID == NULL) {
422 fprintf(stderr,
"unable to open output file for writing\n");
425 fprintf(fileID,
"%ld", slices);
433 sliceOffset += slices;
437 for (i = 0; i < slices; i++) {
439 xAverage = xpAverage = xRMS = x2Average = xp2Average = xxpAverage = 0;
440 yAverage = ypAverage = yRMS = y2Average = yp2Average = yypAverage = 0;
441 pAverage = alphax = alphay = 0;
443 s1 = sMin + (wavelength * i);
444 s2 = sMin + (wavelength * (i + 1));
446 s1 = sMin + (wavelength * (slices - i - 1));
447 s2 = sMin + (wavelength * (slices - i));
449 for (j = 0; j < rows; j++) {
451 if ((s1 <= sValues[j]) && (s2 > sValues[j])) {
454 xAverage += xValues[j];
455 xpAverage += xpValues[j];
456 yAverage += yValues[j];
457 ypAverage += ypValues[j];
458 pAverage += pValues[j];
462 current = N * 2.99792458e8 * (totalCharge / (origRows * wavelength));
463 Ne = totalCharge * N / (e_mks * origRows);
474 removeLocalFit(pValues, sValues, selected, pAverage, rows);
475 for (j = 0; j < rows; j++) {
477 pStDev += sqr(pValues[j] - pAverage);
478 x2Average += sqr(xValues[j] - xAverage);
479 y2Average += sqr(yValues[j] - yAverage);
480 xp2Average += sqr(xpValues[j] - xpAverage);
481 yp2Average += sqr(ypValues[j] - ypAverage);
482 xxpAverage += (xValues[j] - xAverage) * (xpValues[j] - xpAverage);
483 yypAverage += (yValues[j] - yAverage) * (ypValues[j] - ypAverage);
492 pStDev = sqrt(pStDev / (N - 1.0));
499 xRMS = sqrt(x2Average);
500 yRMS = sqrt(y2Average);
501 if ((term = (x2Average * xp2Average) - sqr(xxpAverage)) > 0)
502 xEmittance = sqrt(term) * pAverage;
505 if ((term = (y2Average * yp2Average) - sqr(yypAverage)) > 0)
506 yEmittance = sqrt(term) * pAverage;
510 alphax = -xxpAverage / (xEmittance / pAverage);
511 alphay = -yypAverage / (yEmittance / pAverage);
513 pAverage = pStDev = xEmittance = yEmittance = xRMS = yRMS = xAverage = yAverage = xpAverage = ypAverage = alphax = alphay = current = Ne = 0;
517 if (
SDDS_SetRowValues(&SDDS_output, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, i + sliceOffset,
522 "Sdelta", pAverage > 0 ? pStDev / pAverage : 0,
523 "xemit", xEmittance,
"yemit", yEmittance,
"xrms", xRMS,
"yrms", yRMS,
"xavg", xAverage,
"yavg", yAverage,
"pxavg", xpAverage,
"pyavg", ypAverage,
"alphax", alphax,
"alphay", alphay,
"current", current,
"wakez", 0.0,
"N", N,
"Ne", Ne, NULL) != 1) {
528 fprintf(fileID,
"\n % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E 0.000000E+00", s1, pAverage, pStDev, xEmittance, yEmittance, xRMS, yRMS, xAverage, yAverage, xpAverage, ypAverage, alphax, alphay, current);
559 if (removePTailsFlags & PTAILS_OUTPUT && !
SDDS_Terminate(&SDDS_pTails)) {
567int64_t removeMomentumTails(
double *x,
double *xp,
double *y,
double *yp,
double *s,
double *p,
double *t, int64_t rows,
double limit,
unsigned long flags)
575 static FILE *fp = NULL;
580 if (!(delta = malloc(
sizeof(*delta) * rows)))
583 for (ip = pAve = 0; ip < rows; ip++)
586 for (ip = 0; ip < rows; ip++)
587 delta[ip] = (p[ip] - pAve) / pAve;
589 if (flags & PTAILS_FITMODE) {
590 double slope, intercept, variance;
592 SDDS_Bomb(
"fit failed in momentum tail removal");
593 for (ip = 0; ip < rows; ip++)
594 delta[ip] -= s[ip] * slope + intercept;
598 for (ip = 0; ip < rows; ip++) {
599 if (fabs(delta[ip]) > limit) {
608 delta[ip] = delta[jp];
619 fp = fopen(
"e2g.sdds",
"w");
620 fprintf(fp,
"SDDS1\n&column name=x type=double &end\n");
621 fprintf(fp,
"&column name=xp type=double &end\n");
622 fprintf(fp,
"&column name=y type=double &end\n");
623 fprintf(fp,
"&column name=yp type=double &end\n");
624 fprintf(fp,
"&column name=s type=double &end\n");
625 fprintf(fp,
"&column name=p type=double &end\n");
626 fprintf(fp,
"&data mode=ascii &end\n");
627 fprintf(fp,
"%ld\n", rows);
629 for (ip = 0; ip < rows; ip++)
630 fprintf(fp,
"%le %le %le %le %le %le\n", x[ip], xp[ip], y[ip], yp[ip], s[ip], p[ip]);
636void removeLocalFit(
double *p,
double *s,
short *selected,
double pAverage, int64_t rows) {
637 double slope, intercept, variance;
641 for (i = 0; i < rows; i++)
643 p[i] -= intercept + slope * s[i] - pAverage;
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.
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.
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_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
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.
long unweightedLinearFit(double *xData, double *yData, long nData, double *slope, double *intercept, double *variance)
Performs an unweighted linear fit on the provided data.
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.