Skip to content

Commit 84d23bd

Browse files
author
(Py)thon (Co)llective (M)acro-(P)article Simulation (L)ibrary with (E)xtendible (T)racking (E)lements
authored
Merge pull request #1 from PyCOMPLETE/develop
Develop
2 parents 7d9983b + f0847fc commit 84d23bd

File tree

8 files changed

+2508
-75
lines changed

8 files changed

+2508
-75
lines changed

Detuning.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
1+
from __future__ import division
2+
13
import numpy as np
24

3-
class Detuning:
4-
def __call__(self,jx,jy):
5-
raise NotImplemented;
5+
6+
class Detuning(object):
7+
8+
def __call__(self, jx, jy):
9+
raise NotImplemented
10+
611

712
class LinearDetuning(Detuning):
8-
_startTune = 0.31;
9-
_slopex = 0.0;
10-
_slopey = 0.0;
1113

12-
def __init__(self,startTune,slopex,slopey):
14+
def __init__(self, startTune=0.31, slopex=0, slopey=0):
1315
self._startTune = startTune
1416
self._slopex = slopex
1517
self._slopey = slopey
1618

17-
def __call__(self,jx,jy):
18-
return self._startTune + self._slopex*jx+self._slopey*jy
19+
def __call__(self, jx, jy):
20+
return self._startTune + self._slopex*jx + self._slopey*jy
1921

2022

2123
class FootprintDetuning(Detuning):
22-
_footprint = None;
23-
_plane = None;
24-
25-
#0 for H and 1 for V
26-
def __init__(self,footprint,plane=0):
24+
# 0 for H and 1 for V
25+
def __init__(self, footprint=None, plane=0):
2726
self._footprint = footprint
2827
self._plane = plane
2928

30-
def __call__(self,jx,jy):
29+
def __call__(self, jx, jy):
30+
'''Actions here are given in units of sigma:
31+
sigx = x/sigma_x = sqrt(2*Jx*beta_x)/sqrt(eps_x*beta_x)
32+
= sqrt(2*Jx/eps_x) = sqrt(2*jx).'''
33+
3134
sigx = np.sqrt(2.0*jx)
3235
sigy = np.sqrt(2.0*jy)
33-
return self._footprint.getTunesForAmpl(sigx,sigy)[self._plane]
36+
37+
return self._footprint._getTunesForAmpl(sigx, sigy)[self._plane]

Dispersion.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
class Dispersion:
2-
_detuning = None;
3-
_distribution = None;
4-
_Q = 0.0;
5-
_epsilon = 1E-6;
1+
from __future__ import division
62

7-
def __init__(self, distribution, detuning, Q, epsilon=1E-6):
3+
4+
class Dispersion(object):
5+
6+
def __init__(self, distribution=None, detuning=None, Q=0, epsilon=1E-6):
87
self._distribution = distribution
98
self._detuning = detuning
109
self._Q = Q
1110
self._epsilon = epsilon
1211

13-
def setEpsilon(self,epsilon):
12+
def setEpsilon(self, epsilon):
1413
self._epsilon = epsilon
1514

1615
def getEpsilon(self):
1716
return self._epsilon
1817

1918
def getValue(self, jx, jy):
20-
2119
# DI = (
2220
# (jx * self._distribution.getDJx(jx,jy)) /
2321
# (complex(self._Q - self._detuning(jx,jy), self._epsilon))
@@ -31,10 +29,10 @@ def getValue(self, jx, jy):
3129

3230

3331
class RealDispersion(Dispersion):
34-
def __call__(self,jx,jy):
35-
return self.getValue(jx,jy).real
32+
def __call__(self, jx, jy):
33+
return self.getValue(jx, jy).real
3634

3735

3836
class ImaginaryDispersion(Dispersion):
39-
def __call__(self,jx,jy):
40-
return self.getValue(jx,jy).imag
37+
def __call__(self, jx, jy):
38+
return self.getValue(jx, jy).imag

Distribution.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import numpy as np
2+
23
from abc import ABCMeta, abstractmethod
34

45

@@ -25,10 +26,10 @@ class BiGaussian(Distribution):
2526

2627
def getValue(self, jx, jy):
2728
'''Return pdf of normal bi-Gaussian'''
28-
return np.exp(-(jx + jy));
29+
return np.exp(-(jx + jy))
2930

3031
def getDJx(self, jx, jy):
31-
return -self.getValue(jx, jy);
32+
return -self.getValue(jx, jy)
3233

3334
def getDJy(self, jx, jy):
34-
return -self.getValue(jx, jy);
35+
return -self.getValue(jx, jy)

Footprint.py

Lines changed: 131 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import numpy as np
21
import csv, time
2+
import numpy as np
3+
from scipy.interpolate import griddata
34

45

56
def getStringRep(data,nAmpl,nAngl):
@@ -52,30 +53,31 @@ class Footprint:
5253
#name,amplitudeCount,angleCount,<tunex;tuney>,<...;...>,...,angleCount,...
5354
#TODO make robust
5455
def __init__(self,stringRep,dSigma=1.0):
55-
self._dSigma = dSigma;
56-
self._tunes = []; #tunes[nampl][nangl]['H'/'V']
57-
self._nampl = 0;
58-
self._maxnangl = 0;
59-
self._name = 'noName';
60-
items = stringRep.strip().split(',');
61-
self._name = items[0];
62-
self._nampl = int(items[1]);
63-
current = 2;
56+
self._dSigma = dSigma
57+
self._tunes = [] #tunes[nampl][nangl]['H'/'V']
58+
self._nampl = 0
59+
self._maxnangl = 0
60+
self._name = 'noName'
61+
items = stringRep.strip().split(',')
62+
# print items
63+
self._name = items[0]
64+
self._nampl = int(items[1])
65+
current = 2
6466
for i in np.arange(self._nampl):
65-
self._tunes.append([]);
66-
nangl = int(items[current]);
67+
self._tunes.append([])
68+
nangl = int(items[current])
6769
if nangl > self._maxnangl:
68-
self._maxnangl = nangl;
69-
current = current + 1;
70+
self._maxnangl = nangl
71+
current = current + 1
7072
for j in np.arange(nangl):
71-
self._tunes[i].append([]);
72-
tunesString = items[current].lstrip('<').rstrip('>').split(';');
73-
tunes = {};
73+
self._tunes[i].append([])
74+
tunesString = items[current].lstrip('<').rstrip('>').split(';')
75+
tunes = {}
7476
#print tunesString
75-
tunes['H'] = float(tunesString[0]);
76-
tunes['V'] = float(tunesString[1]);
77-
self._tunes[i][j] = tunes;
78-
current = current + 1;
77+
tunes['H'] = float(tunesString[0])
78+
tunes['V'] = float(tunesString[1])
79+
self._tunes[i][j] = tunes
80+
current = current + 1
7981

8082
def getName(self):
8183
return self._name;
@@ -207,7 +209,7 @@ def drawPlottable(self):
207209
# self.draw(fig,lines)
208210
return lines;
209211

210-
def getIntermediateTunes(self,ampl,angl):
212+
def getIntermediateTunes(self, ampl, angl):
211213
if angl > np.pi/2.0:
212214
print 'ERROR angle ',angl,' is larger than pi/2';
213215
ampl0 = int(ampl/self._dSigma);
@@ -231,7 +233,7 @@ def getIntermediateTunes(self,ampl,angl):
231233
tuneY = (self.getVTune(ampl0,angl0)*(1.0-d1)*(1.0-d2) + self.getVTune(ampl0+1,angl0)*d1*(1.0-d2) + self.getVTune(ampl0,angl0+1)*d2*(1.0-d1) + self.getVTune(ampl0+1,angl0+1)*d1*d2);
232234
return [tuneX,tuneY];
233235

234-
def getTunesForAmpl(self, qx, qy):
236+
def _getTunesForAmpl(self, qx, qy):
235237

236238
ampl = np.sqrt(qx**2 + qy**2)
237239

@@ -243,6 +245,112 @@ def getTunesForAmpl(self, qx, qy):
243245

244246
return self.getIntermediateTunes(ampl, angl)
245247

248+
def getTunesForAmpl(self, sx, sy):
249+
250+
# Base as from MAD-X
251+
n_amp = self.getNbAmpl()-1
252+
n_ang = self.getNbAngl()
253+
d_sigma = self._dSigma
254+
255+
a = np.arange(0., n_amp*d_sigma, d_sigma) + d_sigma
256+
p = np.arange(0., np.pi/2 + np.pi/2/(n_ang-1), np.pi/2/(n_ang-1)) #- np.pi/2/(n_ang-1)
257+
x = np.zeros(n_amp*n_ang)
258+
y = np.zeros(n_amp*n_ang)
259+
260+
i=0
261+
small = 0.05
262+
big = np.sqrt(1.-small**2)
263+
for k, n in enumerate(a):
264+
for l, m in enumerate(p):
265+
if l==50:
266+
x[i] = n*small
267+
y[i] = n*big
268+
elif l==0:
269+
x[i] = n*big
270+
y[i] = n*small
271+
else:
272+
x[i] = n*np.cos(m)
273+
y[i] = n*np.sin(m)
274+
# x[i] = n*np.cos(m)
275+
# y[i] = n*np.sin(m)
276+
i += 1
277+
278+
'''
279+
while (n <= nsigmax)
280+
{
281+
angle = 1.8*m*pi/180;
282+
if (m == 0) {xs=n*big; ys=n*small;}
283+
elseif (m == 50) {xs=n*small; ys=n*big;}
284+
else
285+
{
286+
xs=n*cos(angle);
287+
ys=n*sin(angle);
288+
}
289+
value,xs,ys;
290+
start,fx=xs,fy=ys;
291+
m=m+1;
292+
if (m == 51) { m=0; n=n+0.1;}
293+
};
294+
'''
295+
296+
'''
297+
a = np.arange(0., n_amp*d_sigma, d_sigma) + d_sigma
298+
p = np.arange(0., np.pi/2, np.pi/2/n_ang) - np.pi/2/n_ang
299+
aa, pp = np.meshgrid(a, p)
300+
aa, pp = aa.T, pp.T
301+
x = aa * np.cos(pp)
302+
y = aa * np.sin(pp)
303+
304+
small = a * 0.05
305+
big = a * np.sqrt(1-small**2)
306+
x[:,0] = big
307+
x[:,-1] = small
308+
y[:,0] = small
309+
y[:,-1] = big
310+
311+
x = x.flatten()
312+
y = y.flatten()
313+
'''
314+
315+
qx = np.array([g['H'] for f in self._tunes[1:] for g in f])
316+
qy = np.array([g['V'] for f in self._tunes[1:] for g in f])
317+
318+
# Make regular sampling over 6**2/2/3 = 6 sigma
319+
xi = sx**2/2/3
320+
yi = sy**2/2/3
321+
xi = sx
322+
yi = sy
323+
324+
points = np.array([x, y]).T
325+
pi = np.array([xi, yi]).T
326+
327+
qxi = griddata(points, qx, pi)
328+
qyi = griddata(points, qy, pi)
329+
qxi = griddata(points, qx, pi, fill_value=0.)
330+
qyi = griddata(points, qy, pi, fill_value=0.)
331+
332+
'''
333+
import matplotlib.pyplot as plt
334+
335+
plt.close(1)
336+
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(20, 10))
337+
338+
ax1.scatter(x, y, c=qx, marker='x')
339+
ax1.scatter(xi, yi, c=qxi.T, s=40, lw=0)
340+
341+
# ax2.scatter(x, y, c=qx, marker='x')
342+
# ax2.scatter(xi, yi, c=qxi, s=40, lw=0)
343+
344+
# ax3.scatter(u, v, c=qx, lw=0)
345+
# ax3.set_xlim(-1e-3, 4e-3)
346+
# ax3.set_ylim(-1e-3, 4e-3)
347+
348+
plt.show()
349+
'''
350+
# print qxi
351+
352+
return qxi.T, qyi.T
353+
246354
#
247355
#WARNING use with extreme care, this meant for a very specific type of footprint
248356
#

0 commit comments

Comments
 (0)