OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
profile.cpp
Go to the documentation of this file.
1 /* profile.C
2  profile interpolation class
3 
4  Project: Beam Envelope Tracker (BET)
5 
6  Revision history
7  Date Description Programmer
8  ------------ -------------------------------------------- --------------
9  07-03-06 Created Rene Bakker
10 
11  Last Revision:
12  $Id: profile.C 106 2007-05-08 19:12:24Z bakker $
13 */
14 
15 #include "Ippl.h"
16 #include <iostream>
17 #include <algorithm>
18 #include <cmath>
19 #include <stdlib.h>
20 #include <string.h>
21 
24 #include "Algorithms/bet/profile.h"
25 
26 
27 // global internal functions for integration
28 // -----------------------------------------
29 static Profile *cProfile = NULL;
30 
31 static double f1(double x) {
32  return (cProfile ? cProfile->get(x) : 0.0);
33 }
34 
35 static double f2(double x) {
36  return (cProfile ? pow(cProfile->get(x), 2) : 0.0);
37 }
38 
39 static double f3(double x) {
40  return (cProfile ? fabs(cProfile->get(x)) : 0.0);
41 }
42 
43 Profile::Profile(double v) {
44  n = 0;
45 
46  sf = 1.0;
47  yMin = v;
48  yMax = v;
49 }
50 
51 Profile::Profile(double *_x, double *_y, int _n) :
52  n(_n), x(_x, _x + _n), y(_y, _y + _n) {
53  create();
54 } /* Profile::Profile() */
55 
56 Profile::Profile(char *fname, double eps) {
57  FILE *f;
58  int i, i0;
59  double a, b, m;
60 
61  f = fopen(fname, "r");
62  if(!f) {
63  std::cout << "Profile::Profile: Cannot load profile mapping " << fname << std::endl;
64  }
65  i = 0;
66  m = 0.0;
67  while(fscanf(f, "%lf %lf", &a, &b) == 2) {
68  if(fabs(b) > m) m = fabs(b);
69  ++i;
70  }
71  fclose(f);
72 
73  n = i;
74  x.resize(n);
75  y.resize(n);
76 
77  // read all values
78  f = fopen(fname, "r");
79  for(i = 0; i < n; i++) {
80  int res = fscanf(f, "%lf %lf", &x[i], &y[i]);
81  if (res !=0)
82  ERRORMSG("fscanf in profile.cpp has res!=0" << endl);
83  }
84  fclose(f);
85 
86  // cut tails (if applicable)
87  m = fabs(m * eps);
88  // cut start
89  i0 = 0;
90  while((i0 < n) && (fabs(y[i0]) < m)) ++i0;
91  if((i0 > 0) && (i0 < n)) {
92  for(i = i0; i < n; i++) {
93  x[i-i0] = x[i];
94  y[i-i0] = y[i];
95  }
96  n -= i0;
97  }
98  // cut end
99  i0 = n - 1;
100  while((i0 >= 0) && (fabs(y[i0]) < m)) --i0;
101  if((i0 < (n - 1)) && (i0 >= 0)) n = i0;
102 
103  create();
104 } /* Profile::Profile() */
105 
107  int
108  i, j, k;
109  double
110  sx, sy;
111 
112  sf = 1.0;
113 
114  y2.resize(n);
115  yMax = y[0];
116  yMin = yMax;
117 
118  for(i = 0; i < n; i++) {
119  if(y[i] < yMin) yMin = y[i];
120  if(y[i] > yMax) yMax = y[i];
121  }
122 
123  //sort y according to x
124  std::vector<std::pair<double,double>> xy(n);
125  for (int i=0; i<n; i++) {
126  xy[i] = std::make_pair(x[i],y[i]);
127  }
128 
129  std::sort(xy.begin(), xy.end(),
130  [](const std::pair<double,double> &left, const std::pair<double,double> &right)
131  {return left.first < right.first;});
132 
133  for (int i=0; i<n; i++) {
134  x[i] = xy[i].first;
135  y[i] = xy[i].second;
136  }
137 
138 
139  /* remove points with identical x-value
140  take the average if the situation does occur */
141  j = 0;
142  for(i = 0; i + j < n; i++) {
143  k = 1;
144  sx = x[i+j];
145  sy = y[i+j];
146  while((i + j + k < n) && (x[i+j] == x[i+j+k])) {
147  sx += x[i+j+k];
148  sy += y[i+j];
149  ++k;
150  }
151  x[i] = sx / k;
152  y[i] = sy / k;
153  //printf("i = %d:\tx = %e, y = %e\n",i,x[i],y[i]);
154  j += (k - 1);
155  }
156  n = i;
157 
158  spline(&x[0], &y[0], n, &y2[0]);
159 } /* Profile::create() */
160 
161 double Profile::get(double xa, Interpol_type tp) {
162  double val = 0.0;
163 
164  if(x.empty()==false) {
165  if(xa < x[0]) val = 0.0;
166  else if(xa > x[n-1]) val = 0.0;
167  else switch(tp) {
168  case itype_lin :
169  lsplint(&x[0], &y[0], &y2[0], n, xa, &val);
170  break;
171  default :
172  lsplint(&x[0], &y[0], &y2[0], n, xa, &val);
173  break;
174  }
175  }
176  return (sf * val);
177 } /* Profile::get() */
178 
180  if(yMax > 0.0) sf = 1.0 / yMax;
181  else if(yMin != 0.0) sf = 1.0 / fabs(yMin);
182  else sf = 1.0;
183 } /* Profile:: normalize */
184 
185 void Profile::scale(double v) {
186  sf *= v;
187 } /* Profile::scale() */
188 
189 double Profile::set(double f) {
190  double v = fabs(fabs(yMax) > fabs(yMin) ? yMax : yMin);
191 
192  if(v > 0.0) sf = f / v;
193  else sf = 1.0;
194 
195  return sf;
196 } /* Profile::set() */
197 
198 void Profile::setSF(double value) {
199  sf = value;
200 } /* Profile::setSF() */
201 
202 double Profile::getSF() {
203  return sf;
204 } /* Profile::getSF() */
205 
206 void Profile::dump(char *fname, double dx) {
207  FILE *f;
208 
209  f = fopen(fname, "w");
210  if(f) {
211  dump(f, dx);
212  fclose(f);
213  } else {
214  std::cout << "Profile::Profile: Failed to create profile output:" << fname << std::endl;
215  }
216 }
217 
218 void Profile::dump(FILE *f, double dx) {
219  int i;
220  double xx, dxx;
221 
222  fprintf(f, "SDDS1\n");
223  fprintf(f, "&parameter name=n, type=long, fixed_value=%d &end\n", n);
224  fprintf(f, "&parameter name=sf, type=double, fixed_value=%20.12le &end\n", sf);
225  fprintf(f, "&column name=x, type=double &end\n");
226  fprintf(f, "&column name=y, type=double &end\n");
227  fprintf(f, "&data mode=ascii &end\n");
228 
229  fprintf(f, "! next page\n");
230  fprintf(f, " %d\n", n);
231  for(i = 0; i < n; i++) {
232  fprintf(f, "%20.12le \t %20.12le\n", x[i] + dx, sf * y[i]);
233  }
234  fprintf(f, "! next page\n");
235  fprintf(f, " %d\n", 10 * n);
236 
237  dxx = (x[n-1] - x[0]) / (10 * n - 1);
238  for(i = 0; i < 10 * n; i++) {
239  xx = x[0] + dxx * i;
240  fprintf(f, "%20.12le \t %20.12le\n", xx + dx, get(xx));
241  }
242 } /* Profile::dump() */
243 
245  return n;
246 }
247 
248 double Profile::min() {
249  return sf * yMin;
250 }
251 
252 double Profile::max() {
253  return sf * yMax;
254 }
255 
256 double Profile::xMax() {
257  return ((x.empty()==false) ? x[n-1] : 0.0);
258 }
259 
260 double Profile::xMin() {
261  return ((x.empty()==false) ? x[0] : 0.0);
262 }
263 
264 double Profile::Leff() {
265  double ym;
266 
267  ym = fabs((fabs(yMin) > fabs(yMax)) ? yMin : yMax);
268  cProfile = this;
269  return ((x.empty() || (x[n-1] == x[0]) || (ym == 0.0)) ? 0.0 :
270  fabs(qromb(f1, x[0], x[n-1]) / ym));
271 }
272 
273 double Profile::Leff2() {
274  double ym;
275 
276  ym = pow((fabs(yMin) > fabs(yMax)) ? yMin : yMax, 2);
277  cProfile = this;
278  return ((x.empty() || (x[n-1] == x[0]) || (ym == 0.0)) ? 0.0 :
279  fabs(qromb(f2, x[0], x[n-1]) / ym));
280 }
281 
282 double Profile::Labs() {
283  double ym;
284 
285  ym = fabs((fabs(yMin) > fabs(yMax)) ? yMin : yMax);
286  cProfile = this;
287  return ((x.empty() || (x[n-1] == x[0]) || (ym == 0.0)) ? 0.0 :
288  fabs(qromb(f3, x[0], x[n-1]) / ym));
289 }
std::vector< double > y
Definition: profile.h:36
double getSF()
Definition: profile.cpp:202
double qromb(double(*func)(double), double a, double b, double eps)
Definition: integrate.cpp:126
void create()
Definition: profile.cpp:106
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
double max()
Definition: profile.cpp:252
int n
Definition: profile.h:31
int getN()
Definition: profile.cpp:244
double yMin
Definition: profile.h:33
double yMax
Definition: profile.h:33
void scale(double)
Definition: profile.cpp:185
double get(double, Interpol_type=itype_spline)
Definition: profile.cpp:161
double Labs()
Definition: profile.cpp:282
double min()
Definition: profile.cpp:248
Profile(double)
Definition: profile.cpp:43
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
void normalize()
Definition: profile.cpp:179
double set(double)
Definition: profile.cpp:189
double sf
Definition: profile.h:33
void setSF(double)
Definition: profile.cpp:198
void dump(FILE *=stdout, double=0.0)
Definition: profile.cpp:218
double xMin()
Definition: profile.cpp:260
double Leff2()
Definition: profile.cpp:273
Interpol_type
Definition: profile.h:24
double Leff()
Definition: profile.cpp:264
void spline(double x[], double y[], int n, double y2[])
Definition: interpol.cpp:61
void lsplint(double xa[], double ya[], double y2a[], int n, double x, double *y)
Definition: interpol.cpp:137
double xMax()
Definition: profile.cpp:256
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::vector< double > y2
Definition: profile.h:36