10
10
11
11
import abc
12
12
import re
13
+ import math
13
14
from abc import ABC
14
15
from collections .abc import Generator , Iterable
15
16
from copy import copy , deepcopy
16
17
from typing import Any , Optional
17
18
18
- import numpy
19
+ import numpy as np
19
20
20
21
# noinspection PyProtectedMember
21
22
from .variables import _nop
22
23
24
+ _zero6 = np .zeros (6 )
25
+ _eye6 = np .eye (6 , order = "F" )
23
26
24
- def _array (value , shape = (- 1 ,), dtype = numpy .float64 ):
27
+
28
+ def _array (value , shape = (- 1 ,), dtype = np .float64 ):
25
29
# Ensure proper ordering(F) and alignment(A) for "C" access in integrators
26
- return numpy .require (value , dtype = dtype , requirements = ["F" , "A" ]).reshape (
30
+ return np .require (value , dtype = dtype , requirements = ["F" , "A" ]).reshape (
27
31
shape , order = "F"
28
32
)
29
33
@@ -408,7 +412,7 @@ def definition(self) -> tuple[str, tuple, dict]:
408
412
keywords = {
409
413
k : v
410
414
for k , v in attrs .items ()
411
- if not numpy .array_equal (v , getattr (defelem , k , None ))
415
+ if not np .array_equal (v , getattr (defelem , k , None ))
412
416
}
413
417
return self .__class__ .__name__ , arguments , keywords
414
418
@@ -448,6 +452,60 @@ def is_collective(self) -> bool:
448
452
""":py:obj:`True` if the element involves collective effects"""
449
453
return self ._get_collective ()
450
454
455
+ def _getshift (self , idx : int ):
456
+ t1 = getattr (self , "T1" , _zero6 )
457
+ t2 = getattr (self , "T2" , _zero6 )
458
+ return 0.5 * float (t2 [idx ] - t1 [idx ])
459
+
460
+ def _setshift (self , value : float , idx : int ) -> None :
461
+ t1 = getattr (self , "T1" , _zero6 .copy ())
462
+ t2 = getattr (self , "T2" , _zero6 .copy ())
463
+ sm = 0.5 * (t2 [idx ] + t1 [idx ])
464
+ t2 [idx ] = sm + value
465
+ t1 [idx ] = sm - value
466
+ self .T1 = t1
467
+ self .T2 = t2
468
+
469
+ @property
470
+ def dx (self ) -> float :
471
+ """Horizontal element shift"""
472
+ return self ._getshift (0 )
473
+
474
+ @dx .setter
475
+ def dx (self , value : float ) -> None :
476
+ self ._setshift (value , 0 )
477
+
478
+ @property
479
+ def dy (self ) -> float :
480
+ """Vertical element shift"""
481
+ return self ._getshift (2 )
482
+
483
+ @dy .setter
484
+ def dy (self , value : float ) -> None :
485
+ self ._setshift (value , 2 )
486
+
487
+ @property
488
+ def tilt (self ) -> float :
489
+ """Element tilt"""
490
+ r1 = getattr (self , "R1" , _eye6 )
491
+ r2 = getattr (self , "R2" , _eye6 )
492
+ c = float (r2 [0 , 0 ] + r1 [0 , 0 ])
493
+ s = float (r2 [2 , 0 ] - r1 [2 , 0 ])
494
+ return math .atan2 (s , c )
495
+
496
+ @tilt .setter
497
+ def tilt (self , value : float ) -> None :
498
+ r1 = getattr (self , "R1" , _eye6 .copy ())
499
+ r2 = getattr (self , "R2" , _eye6 .copy ())
500
+ ct , st = math .cos (value ), math .sin (value )
501
+ r44 = np .diag ([ct , ct , ct , ct ])
502
+ r44 [0 , 2 ] = r44 [1 , 3 ] = st
503
+ r44 [2 , 0 ] = r44 [3 , 1 ] = - st
504
+ r1 [:4 , :4 ] = r44
505
+ r2 [:4 , :4 ] = r44 .T
506
+ self .R1 = r1
507
+ self .R2 = r2
508
+
451
509
452
510
class LongElement (Element ):
453
511
"""Base class for long elements"""
@@ -480,15 +538,15 @@ def popattr(element, attr):
480
538
delattr (element , attr )
481
539
return attr , val
482
540
483
- frac = numpy .asarray (frac , dtype = float )
541
+ frac = np .asarray (frac , dtype = float )
484
542
el = self .copy ()
485
543
# Remove entrance and exit attributes
486
544
fin = dict (
487
545
popattr (el , key ) for key in vars (self ) if key in self ._entrance_fields
488
546
)
489
547
fout = dict (popattr (el , key ) for key in vars (self ) if key in self ._exit_fields )
490
548
# Split element
491
- element_list = [el ._part (f , numpy .sum (frac )) for f in frac ]
549
+ element_list = [el ._part (f , np .sum (frac )) for f in frac ]
492
550
# Restore entrance and exit attributes
493
551
for key , value in fin .items ():
494
552
setattr (element_list [0 ], key , value )
@@ -505,7 +563,7 @@ def compatible_field(fieldname):
505
563
elif f1 is None or f2 is None : # only one
506
564
return False
507
565
else : # both
508
- return numpy .all (f1 == f2 )
566
+ return np .all (f1 == f2 )
509
567
510
568
if not (type (other ) is type (self ) and self .PassMethod == other .PassMethod ):
511
569
return False
@@ -538,13 +596,13 @@ def __init__(self, family_name: str, **kwargs):
538
596
Default PassMethod: ``BeamMomentsPass``
539
597
"""
540
598
kwargs .setdefault ("PassMethod" , "BeamMomentsPass" )
541
- self ._stds = numpy .zeros ((6 , 1 , 1 ), order = "F" )
542
- self ._means = numpy .zeros ((6 , 1 , 1 ), order = "F" )
599
+ self ._stds = np .zeros ((6 , 1 , 1 ), order = "F" )
600
+ self ._means = np .zeros ((6 , 1 , 1 ), order = "F" )
543
601
super ().__init__ (family_name , ** kwargs )
544
602
545
603
def set_buffers (self , nturns , nbunch ):
546
- self ._stds = numpy .zeros ((6 , nbunch , nturns ), order = "F" )
547
- self ._means = numpy .zeros ((6 , nbunch , nturns ), order = "F" )
604
+ self ._stds = np .zeros ((6 , nbunch , nturns ), order = "F" )
605
+ self ._means = np .zeros ((6 , nbunch , nturns ), order = "F" )
548
606
549
607
@property
550
608
def stds (self ):
@@ -583,20 +641,20 @@ def __init__(self, family_name: str, nslice: int, **kwargs):
583
641
self .startturn = self ._startturn
584
642
self .endturn = self ._endturn
585
643
self ._dturns = self .endturn - self .startturn
586
- self ._stds = numpy .zeros ((3 , nslice , self ._dturns ), order = "F" )
587
- self ._means = numpy .zeros ((3 , nslice , self ._dturns ), order = "F" )
588
- self ._spos = numpy .zeros ((nslice , self ._dturns ), order = "F" )
589
- self ._weights = numpy .zeros ((nslice , self ._dturns ), order = "F" )
644
+ self ._stds = np .zeros ((3 , nslice , self ._dturns ), order = "F" )
645
+ self ._means = np .zeros ((3 , nslice , self ._dturns ), order = "F" )
646
+ self ._spos = np .zeros ((nslice , self ._dturns ), order = "F" )
647
+ self ._weights = np .zeros ((nslice , self ._dturns ), order = "F" )
590
648
self .set_buffers (self ._endturn , 1 )
591
649
592
650
def set_buffers (self , nturns , nbunch ):
593
651
self .endturn = min (self .endturn , nturns )
594
652
self ._dturns = self .endturn - self .startturn
595
653
self ._nbunch = nbunch
596
- self ._stds = numpy .zeros ((3 , nbunch * self .nslice , self ._dturns ), order = "F" )
597
- self ._means = numpy .zeros ((3 , nbunch * self .nslice , self ._dturns ), order = "F" )
598
- self ._spos = numpy .zeros ((nbunch * self .nslice , self ._dturns ), order = "F" )
599
- self ._weights = numpy .zeros ((nbunch * self .nslice , self ._dturns ), order = "F" )
654
+ self ._stds = np .zeros ((3 , nbunch * self .nslice , self ._dturns ), order = "F" )
655
+ self ._means = np .zeros ((3 , nbunch * self .nslice , self ._dturns ), order = "F" )
656
+ self ._spos = np .zeros ((nbunch * self .nslice , self ._dturns ), order = "F" )
657
+ self ._weights = np .zeros ((nbunch * self .nslice , self ._dturns ), order = "F" )
600
658
601
659
@property
602
660
def stds (self ):
@@ -730,11 +788,11 @@ def insert(
730
788
"""
731
789
frac , elements = zip (* insert_list )
732
790
lg = [0.0 if el is None else el .Length for el in elements ]
733
- fr = numpy .asarray (frac , dtype = float )
734
- lg = 0.5 * numpy .asarray (lg , dtype = float ) / self .Length
735
- drfrac = numpy .hstack ((fr - lg , 1.0 )) - numpy .hstack ((0.0 , fr + lg ))
791
+ fr = np .asarray (frac , dtype = float )
792
+ lg = 0.5 * np .asarray (lg , dtype = float ) / self .Length
793
+ drfrac = np .hstack ((fr - lg , 1.0 )) - np .hstack ((0.0 , fr + lg ))
736
794
long_elems = drfrac != 0.0
737
- drifts = numpy .ndarray ((len (drfrac ),), dtype = "O" )
795
+ drifts = np .ndarray ((len (drfrac ),), dtype = "O" )
738
796
drifts [long_elems ] = self .divide (drfrac [long_elems ])
739
797
nline = len (drifts ) + len (elements )
740
798
line = [None ] * nline # type: list[Optional[Element]]
@@ -783,12 +841,12 @@ def __init__(self, family_name: str, poly_a, poly_b, **kwargs):
783
841
"""
784
842
785
843
def getpol (poly ):
786
- nonzero = numpy .flatnonzero (poly != 0.0 )
844
+ nonzero = np .flatnonzero (poly != 0.0 )
787
845
return poly , len (poly ), nonzero [- 1 ] if len (nonzero ) > 0 else - 1
788
846
789
847
def lengthen (poly , dl ):
790
848
if dl > 0 :
791
- return numpy .concatenate ((poly , numpy .zeros (dl )))
849
+ return np .concatenate ((poly , np .zeros (dl )))
792
850
else :
793
851
return poly
794
852
@@ -1198,7 +1256,7 @@ def __init__(self, family_name: str, m66=None, **kwargs):
1198
1256
Default PassMethod: ``Matrix66Pass``
1199
1257
"""
1200
1258
if m66 is None :
1201
- m66 = numpy .identity (6 )
1259
+ m66 = np .identity (6 )
1202
1260
kwargs .setdefault ("PassMethod" , "Matrix66Pass" )
1203
1261
kwargs .setdefault ("M66" , m66 )
1204
1262
super ().__init__ (family_name , ** kwargs )
@@ -1311,24 +1369,24 @@ def __init__(
1311
1369
if taux == 0.0 :
1312
1370
dampx = 1
1313
1371
else :
1314
- dampx = numpy .exp (- 1 / taux )
1372
+ dampx = np .exp (- 1 / taux )
1315
1373
1316
1374
assert tauy >= 0.0 , "tauy must be greater than or equal to 0"
1317
1375
if tauy == 0.0 :
1318
1376
dampy = 1
1319
1377
else :
1320
- dampy = numpy .exp (- 1 / tauy )
1378
+ dampy = np .exp (- 1 / tauy )
1321
1379
1322
1380
assert tauz >= 0.0 , "tauz must be greater than or equal to 0"
1323
1381
if tauz == 0.0 :
1324
1382
dampz = 1
1325
1383
else :
1326
- dampz = numpy .exp (- 1 / tauz )
1384
+ dampz = np .exp (- 1 / tauz )
1327
1385
1328
1386
kwargs .setdefault ("PassMethod" , self .default_pass [True ])
1329
1387
kwargs .setdefault ("U0" , U0 )
1330
1388
kwargs .setdefault (
1331
- "damp_mat_diag" , numpy .array ([dampx , dampx , dampy , dampy , dampz , dampz ])
1389
+ "damp_mat_diag" , np .array ([dampx , dampx , dampy , dampy , dampz , dampz ])
1332
1390
)
1333
1391
1334
1392
super ().__init__ (family_name , ** kwargs )
@@ -1449,7 +1507,7 @@ class QuantumDiffusion(_DictLongtMotion, Element):
1449
1507
default_pass = {False : "IdentityPass" , True : "QuantDiffPass" }
1450
1508
_conversions = dict (Element ._conversions , Lmatp = _array66 )
1451
1509
1452
- def __init__ (self , family_name : str , lmatp : numpy .ndarray , ** kwargs ):
1510
+ def __init__ (self , family_name : str , lmatp : np .ndarray , ** kwargs ):
1453
1511
"""Quantum diffusion element
1454
1512
1455
1513
Args:
0 commit comments