/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ /* $Log: elegant2genesis.c,v $ Revision 1.22 2008/08/13 15:53:33 borland Added -localFit option to remove local chirp. Revision 1.21 2006/10/19 17:55:39 soliday Updated to work with linux-x86_64. Revision 1.20 2003/09/02 19:16:02 soliday Cleaned up code for Linux. Revision 1.19 2002/08/14 17:12:36 soliday Added Open License Revision 1.18 2002/07/01 18:35:08 borland Added option to reverse order of rows in file. Added 't' column. Revision 1.17 2001/11/21 16:30:29 borland No longer emits NaN values when the number of particles in a slice is zero. Revision 1.16 2001/08/08 19:20:22 borland Added ability to output the filtered beam data using the -removePTails option. Revision 1.15 2001/08/08 00:58:48 borland Added -removePTails option, which permits removing momentum tails from the beam. Revision 1.14 2001/07/11 15:37:51 borland Added -pipe option. Revision 1.13 2001/05/03 20:53:53 soliday Fixed a problem related to the last version that was merged with a previous version. Revision 1.12 2001/04/03 18:23:16 borland Added -chargeParameter option, which permits taking the beam charge from a parameter in the SDDS input file. Revision 1.11 2001/01/23 19:14:55 soliday Standardized usage message. Revision 1.10 2000/06/02 20:01:01 soliday To be consistant with GENESIS, where dgamma is the rms value of gamma, dgamma is calculated the same way it was before revision 1.5. Revision 1.9 2000/06/01 21:42:55 borland SDDS output is now the default. Added -steer option. Improved usage message. Revision 1.8 2000/05/31 20:31:17 soliday Fixed small bug from last change. Revision 1.7 2000/05/31 20:20:14 soliday Added alphax and alphay in ascii output. Revision 1.6 2000/05/31 19:28:19 borland Added gammaStDev column. Revision 1.5 2000/05/31 17:48:48 borland Fixed bug in computation of delta gamma (was computing delta s). Simplified computation of alphax and alphay, and used geometric emittance in place of normalized emittance. Revision 1.4 2000/05/31 15:20:55 soliday Added correct computation for alphax and alphay. Revision 1.3 2000/01/06 22:18:15 soliday Multiplied the previous value of Emittance by gamma to get the correct emittance. Divided the previous value of Current by the wavelength to get the correct value. Revision 1.2 2000/01/06 21:29:19 soliday Fixed a bug when calculating the emittance Revision 1.1 2000/01/06 18:02:25 soliday This program is used to convert the output file from elegant into the beamline file used by genesis. */ #include "mdb.h" #include "SDDS.h" #include "scan.h" #define SET_WAVELENGTH 0 #define SET_SLICES 1 #define SET_TOTALCHARGE 2 #define SET_TEXTOUTPUT 3 #define SET_STEER 4 #define SET_CHARGEPARAMETER 5 #define SET_PIPE 6 #define SET_REMPTAILS 7 #define SET_REVERSEORDER 8 #define SET_LOCAL_FIT 9 #define N_OPTIONS 10 char *option[N_OPTIONS] = {"wavelength", "slices", "totalcharge", "textoutput", "steer", "chargeparameter", "pipe", "removePTails", "reverseorder", "localfit"}; char *USAGE = "elegant2genesis [] [] [-pipe=[in][,out]] [-textOutput]\n\ [-totalCharge= | -chargeParameter=]\n\ [-wavelength= | -slices=]\n\ [-steer] [-removePTails=deltaLimit=[,fit][,beamOutput=]]\n\ [-reverseOrder] [-localFit]\n\n\ textOutput Make the output file a text file instead of an SDDS file.\n\ totalCharge Specify the total charge in Coulombs.\n\ chargeParameter Specify the name of a parameter in the input file that gives\n\ the total charge in Coulombs.\n\ wavelength Specify the wavelength of light in meters.\n\ slices Specify the number of slices to cut the beam into.\n\ steer Force the x, x', y, and y' centroids for the whole beam to zero.\n\ Slices may still have nonzero centroids.\n\ removePTail Removes the momentum tails from the beam. deltaLimit is the maximum\n\ |p-

|/

that will be kept. If 'fit' is given, then a linear fit to\n\ (t, p) is done and removal is based on residuals from this fit.\n\ If 'beamOutput' is given, the filtered beam is written to the named\n\ file for review.\n\ reverseOrder By default, the data for the head of the beam comes first. This\n\ option causes elegant to put the data for the tail of the beam \n\ first.\n\ localFit If given, then for each slice the program performs a local linear\n\ fit of momentum vs time, and subtracts it from the momentum data.\n\ This removes a contribution to the energy spread, but may not be\n\ appropriate if slices are longer than the cooperation length.\n\n\ Program by Robert Soliday. This is version 2, August 2008, M. Borland. ("__DATE__")\n"; #define PTAILS_DELTALIMIT 0x0001U #define PTAILS_FITMODE 0x0002U #define PTAILS_OUTPUT 0X0004U long removeMomentumTails(double *x, double *xp, double *y, double *yp, double *s, double *p, double *t, long rows, double limit, unsigned long flags); void removeLocalFit(double *p, double *s, short *selected, double pAverage, long rows); /* ********** */ int main(int argc, char **argv) { SDDS_DATASET SDDS_input, SDDS_output, SDDS_pTails; FILE *fileID=NULL; SCANNED_ARG *s_arg; long i, j, i_arg; char *input, *output; unsigned long pipeFlags=0; long noWarnings=0, tmpfile_used=0; long retval, origRows, rows, sddsOutput=1, steer=0, firstOne, sliceOffset=0; long reverseOrder=0; char *chargeParameter; unsigned long removePTailsFlags = 0; double pTailsDeltaLimit, term; char *pTailsOutputFile = NULL; long localFit = 0; short *selected; char column[7][15] = {"x", "xp", "y", "yp", "t", "p", "particleID"}; long columnIndex[7]; double *tValues, *sValues, *xValues, *xpValues, *yValues, *ypValues, *pValues; double sAverage, pAverage, pStDev; double xAverage, xpAverage, xRMS, x2Average, xp2Average, xxpAverage, xEmittance; double yAverage, ypAverage, yRMS, y2Average, yp2Average, yypAverage, yEmittance; double sMin=1, sMax=-1, s1, s2; /* double pMin, pMax; */ double alphax, alphay; double wavelength=0.0001; double totalCharge=0; double current; long slices=4; long tmp=0; long N=0; input = output = NULL; sValues = NULL; chargeParameter = NULL; selected = NULL; SDDS_RegisterProgramName(argv[0]); argc = scanargs(&s_arg, argc, argv); if (argc<3) bomb(NULL, USAGE); /* parse the command line */ for (i_arg=1; i_arg=1) { rows = origRows = SDDS_RowCount(&SDDS_input); if (rows < 1) { fprintf(stderr, "error: no rows found for page %ld\n", retval); exit(1); } /* get all the needed column data */ if (!(tValues = SDDS_GetNumericColumn(&SDDS_input, "t", SDDS_DOUBLE)) || !(xValues = SDDS_GetNumericColumn(&SDDS_input, "x", SDDS_DOUBLE)) || !(xpValues = SDDS_GetNumericColumn(&SDDS_input, "xp", SDDS_DOUBLE)) || !(yValues = SDDS_GetNumericColumn(&SDDS_input, "y", SDDS_DOUBLE)) || !(ypValues = SDDS_GetNumericColumn(&SDDS_input, "yp", SDDS_DOUBLE)) || !(pValues = SDDS_GetNumericColumn(&SDDS_input, "p", SDDS_DOUBLE))) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } if (chargeParameter && !SDDS_GetParameterAsDouble(&SDDS_input, chargeParameter, &totalCharge)) SDDS_Bomb("unable to read charge from file"); if ((!(tValues)) || (!(xValues)) || (!(xpValues)) || (!(yValues)) || (!(ypValues)) || (!(pValues))) { fprintf(stderr, "error: invalid data for page %ld\n", retval); exit(1); } selected = realloc(selected, sizeof(*selected)*rows); sValues = realloc(sValues, sizeof(*sValues)*rows); sAverage = xAverage = xpAverage = yAverage = ypAverage = 0; for (i=0;i sValues[j])) { selected[j] = 1; N++; xAverage += xValues[j]; xpAverage += xpValues[j]; yAverage += yValues[j]; ypAverage += ypValues[j]; pAverage += pValues[j]; } } if (N>2) { current = N * 2.99792458e8 * (totalCharge/(origRows * wavelength)); xAverage /= N; yAverage /= N; xpAverage /= N; ypAverage /= N; pAverage /= N; /* pMin = pMax = pAverage; */ pStDev = 0; if (localFit) removeLocalFit(pValues, sValues, selected, pAverage, rows); for (j=0;j pMax) pMax = pValues[j]; */ } } pStDev = sqrt(pStDev/(N-1.0)); x2Average /= N; y2Average /= N; xp2Average /= N; yp2Average /= N; xxpAverage /= N; yypAverage /= N; xRMS = sqrt(x2Average); yRMS = sqrt(y2Average); if ((term = (x2Average * xp2Average) - sqr(xxpAverage))>0) xEmittance = sqrt(term)*pAverage; else xEmittance = 0; if ((term = (y2Average * yp2Average) - sqr(yypAverage))>0) yEmittance = sqrt(term)*pAverage; else yEmittance = 0; alphax = -xxpAverage/(xEmittance/pAverage); alphay = -yypAverage/(yEmittance/pAverage); } else { pAverage = pStDev = xEmittance = yEmittance = xRMS = yRMS = xAverage = yAverage = xpAverage = ypAverage = alphax = alphay = current = 0; } if (sddsOutput) { if (SDDS_SetRowValues(&SDDS_output, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, i+sliceOffset, "s", s1, "t", -s1/c_mks, "gamma", pAverage, "dgamma", pStDev, /* This was commented out to be consistant with GENESIS where dgamma is the rms value of gamma "dgamma", pMax - pMin, "gammaStDev", pStDev, */ "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, NULL) != 1) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } } else { 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); } } free(tValues); free(xValues); free(xpValues); free(yValues); free(ypValues); free(pValues); } free(sValues); /* close the output file */ if (sddsOutput) { if (!SDDS_WritePage(&SDDS_output)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } if (!SDDS_Terminate(&SDDS_output)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } } else { fclose(fileID); } /* close the input file */ if (!SDDS_Terminate(&SDDS_input)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } if (removePTailsFlags&PTAILS_OUTPUT && !SDDS_Terminate(&SDDS_pTails)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); exit(1); } return(0); } long removeMomentumTails(double *x, double *xp, double *y, double *yp, double *s, double *p, double *t, long rows, double limit, unsigned long flags) /* t is equivalent to s. It is filtered here for convenience in output * to an elegant-type file */ { double *delta, pAve; long ip, jp; #if defined(DEBUG) static FILE *fp = NULL; #endif if (!rows) return rows; if (!(delta = malloc(sizeof(*delta)*rows))) SDDS_Bomb("memory allocation failure"); for (ip=pAve=0; iplimit) { if (jp>ip) { x[ip] = x[jp]; xp[ip] = xp[jp]; y[ip] = y[jp]; yp[ip] = yp[jp]; s[ip] = s[jp]; p[ip] = p[jp]; t[ip] = t[jp]; delta[ip] = delta[jp]; jp --; ip --; } rows --; } } free(delta); #if defined(DEBUG) if (!fp) { fp = fopen("e2g.sdds", "w"); fprintf(fp, "SDDS1\n&column name=x type=double &end\n"); fprintf(fp, "&column name=xp type=double &end\n"); fprintf(fp, "&column name=y type=double &end\n"); fprintf(fp, "&column name=yp type=double &end\n"); fprintf(fp, "&column name=s type=double &end\n"); fprintf(fp, "&column name=p type=double &end\n"); fprintf(fp, "&data mode=ascii &end\n"); fprintf(fp, "%ld\n", rows); } for (ip=0; ip