syned 1.0.47__py3-none-any.whl → 1.0.49__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. syned/beamline/__init__.py +1 -1
  2. syned/beamline/beamline.py +155 -155
  3. syned/beamline/beamline_element.py +76 -76
  4. syned/beamline/element_coordinates.py +199 -199
  5. syned/beamline/optical_element.py +47 -47
  6. syned/beamline/optical_element_with_surface_shape.py +126 -126
  7. syned/beamline/optical_elements/__init__.py +1 -1
  8. syned/beamline/optical_elements/absorbers/absorber.py +21 -21
  9. syned/beamline/optical_elements/absorbers/beam_stopper.py +63 -63
  10. syned/beamline/optical_elements/absorbers/filter.py +61 -61
  11. syned/beamline/optical_elements/absorbers/holed_filter.py +67 -67
  12. syned/beamline/optical_elements/absorbers/slit.py +80 -80
  13. syned/beamline/optical_elements/crystals/__init__.py +1 -1
  14. syned/beamline/optical_elements/crystals/crystal.py +70 -70
  15. syned/beamline/optical_elements/gratings/__init__.py +1 -1
  16. syned/beamline/optical_elements/gratings/grating.py +279 -279
  17. syned/beamline/optical_elements/ideal_elements/__init__.py +1 -1
  18. syned/beamline/optical_elements/ideal_elements/ideal_element.py +15 -15
  19. syned/beamline/optical_elements/ideal_elements/ideal_fzp.py +183 -183
  20. syned/beamline/optical_elements/ideal_elements/ideal_lens.py +54 -54
  21. syned/beamline/optical_elements/ideal_elements/screen.py +15 -15
  22. syned/beamline/optical_elements/mirrors/__init__.py +1 -1
  23. syned/beamline/optical_elements/mirrors/mirror.py +39 -39
  24. syned/beamline/optical_elements/multilayers/__init__.py +46 -46
  25. syned/beamline/optical_elements/multilayers/multilayer.py +45 -45
  26. syned/beamline/optical_elements/refractors/__init__.py +1 -1
  27. syned/beamline/optical_elements/refractors/crl.py +79 -79
  28. syned/beamline/optical_elements/refractors/interface.py +60 -60
  29. syned/beamline/optical_elements/refractors/lens.py +105 -105
  30. syned/beamline/shape.py +2884 -2803
  31. syned/storage_ring/__init__.py +1 -1
  32. syned/storage_ring/electron_beam.py +804 -804
  33. syned/storage_ring/empty_light_source.py +40 -40
  34. syned/storage_ring/light_source.py +90 -90
  35. syned/storage_ring/magnetic_structure.py +8 -8
  36. syned/storage_ring/magnetic_structures/__init__.py +1 -1
  37. syned/storage_ring/magnetic_structures/bending_magnet.py +329 -329
  38. syned/storage_ring/magnetic_structures/insertion_device.py +169 -169
  39. syned/storage_ring/magnetic_structures/undulator.py +413 -413
  40. syned/storage_ring/magnetic_structures/wiggler.py +27 -27
  41. syned/syned_object.py +273 -264
  42. syned/util/__init__.py +21 -21
  43. syned/util/json_tools.py +196 -198
  44. syned/widget/widget_decorator.py +66 -66
  45. {syned-1.0.47.dist-info → syned-1.0.49.dist-info}/METADATA +88 -88
  46. syned-1.0.49.dist-info/RECORD +52 -0
  47. {syned-1.0.47.dist-info → syned-1.0.49.dist-info}/WHEEL +1 -1
  48. {syned-1.0.47.dist-info → syned-1.0.49.dist-info}/licenses/LICENSE +20 -20
  49. syned/__test/__init__.py +0 -46
  50. syned/__test/test.py +0 -28
  51. syned-1.0.47.dist-info/RECORD +0 -54
  52. {syned-1.0.47.dist-info → syned-1.0.49.dist-info}/top_level.txt +0 -0
@@ -1,27 +1,27 @@
1
- from syned.storage_ring.magnetic_structures.insertion_device import InsertionDevice
2
-
3
- class Wiggler(InsertionDevice):
4
- """
5
- Constructor.
6
-
7
- Parameters
8
- ----------
9
- K_vertical : float, optional
10
- The deflection K parameter corresponding to magnetic field in the vertical direction.
11
- K_horizontal : float, optional
12
- The deflection K parameter corresponding to magnetic field in the horizontal direction.
13
- period_length : float, optional
14
- The ID period in m.
15
- number_of_periods : float, optional
16
- The number of periods. It may be a float, considering that number_of_periods = ID_length / period_length.
17
-
18
- """
19
-
20
- def __init__(self, K_vertical = 0.0, K_horizontal = 0.0,period_length = 0.0, number_of_periods = 1):
21
- InsertionDevice.__init__(self,
22
- K_vertical=K_vertical,
23
- K_horizontal=K_horizontal,
24
- period_length=period_length,
25
- number_of_periods=number_of_periods)
26
-
27
-
1
+ from syned.storage_ring.magnetic_structures.insertion_device import InsertionDevice
2
+
3
+ class Wiggler(InsertionDevice):
4
+ """
5
+ Constructor.
6
+
7
+ Parameters
8
+ ----------
9
+ K_vertical : float, optional
10
+ The deflection K parameter corresponding to magnetic field in the vertical direction.
11
+ K_horizontal : float, optional
12
+ The deflection K parameter corresponding to magnetic field in the horizontal direction.
13
+ period_length : float, optional
14
+ The ID period in m.
15
+ number_of_periods : float, optional
16
+ The number of periods. It may be a float, considering that number_of_periods = ID_length / period_length.
17
+
18
+ """
19
+
20
+ def __init__(self, K_vertical = 0.0, K_horizontal = 0.0,period_length = 0.0, number_of_periods = 1):
21
+ InsertionDevice.__init__(self,
22
+ K_vertical=K_vertical,
23
+ K_horizontal=K_horizontal,
24
+ period_length=period_length,
25
+ number_of_periods=number_of_periods)
26
+
27
+
syned/syned_object.py CHANGED
@@ -1,264 +1,273 @@
1
- import copy
2
- from collections import OrderedDict
3
- try:
4
- import json_tricks as json # to save numpy arrays
5
- except:
6
- import json
7
-
8
- # TODO: although basic functionality is implemented, the use of exec should be replace by introspection tools
9
- class SynedObject(object):
10
-
11
- # ---------------------------------------------------------------------------------------------------------
12
- # This override is necessary to avoid TypeError: cannot pickle '_thread.lock' object while duplicating
13
- # that occurs while enabling/disabling connectors
14
- #
15
- # When an attribute is an object that contains non pickable attributes, we make a shallow copy of it
16
- # ---------------------------------------------------------------------------------------------------------
17
-
18
- def __deepcopy__(self, memodict={}):
19
- cls = self.__class__
20
- result = cls.__new__(cls)
21
- memodict[id(self)] = result
22
- for k, v in self.__dict__.items():
23
- try: setattr(result, k, copy.deepcopy(v, memodict))
24
- except TypeError: setattr(result, k, copy.copy(v))
25
- return result
26
-
27
- """
28
- This is the base object for SYNED.
29
-
30
- It includes the methods of the common interface to allow json file input/output and info mechanism
31
-
32
- These standard methods are:
33
- * keys()
34
- * to_dictionary()
35
- * to_full_dictionary()
36
- * to_json()
37
- * info()
38
- * set_value_from_key_name()
39
- * get_value_from_key_name()
40
-
41
- """
42
-
43
- def _set_support_text(self, text):
44
- ordered_support_dict = OrderedDict()
45
- for e in text:
46
- ordered_support_dict[e[0]] = (e[1], e[2])
47
- self._support_dictionary = ordered_support_dict
48
-
49
- def _add_support_text(self, text):
50
- try:
51
- for e in text:
52
- self._support_dictionary[e[0]] = (e[1], e[2])
53
- except:
54
- self._set_support_text(text)
55
-
56
- #
57
- # this is the common interface to allow json file input/output and info mechanism
58
- #
59
- # standard methods are:
60
- # keys
61
- # to_dictionary
62
- # to_full_dictionary
63
- # to_json
64
- # info
65
- # set_value_from_key_name
66
- # get_value_from_key_name
67
- #
68
- def keys(self):
69
- """
70
- Returns the keys of the supporting doctionary.
71
- Returns
72
- -------
73
- list
74
- A list of keys.
75
-
76
- """
77
- try:
78
- return self._support_dictionary.keys()
79
- except:
80
- return None
81
-
82
- def to_dictionary(self):
83
- """
84
- Returns a dictionary with the object fields.
85
-
86
- Some dictionary keys may contain SYNED instances. Use to_full_dictionary to recurrently expand these objects
87
- in their basic ingredients.
88
-
89
- Returns
90
- -------
91
- dict
92
- A dictionary with the data.
93
-
94
- """
95
- dict_to_save = OrderedDict()
96
- dict_to_save.update({"CLASS_NAME":self.__class__.__name__})
97
-
98
- try:
99
- if self.keys() is not None:
100
- for key in self.keys():
101
- tmp1 = eval("self._%s" % (key) )
102
- if isinstance(tmp1,SynedObject):
103
- dict_to_save[key] = tmp1.to_dictionary()
104
- else:
105
- dict_to_save[key] = tmp1
106
- except:
107
- pass
108
-
109
- return dict_to_save
110
-
111
- def to_full_dictionary(self):
112
- """
113
- Returns a dictionary with the object fields, including other syned objects embedded or list of elements.
114
-
115
- The "full" means that the SYNED instances found are recurrently expanded in their basic ingredients.
116
-
117
- Returns
118
- -------
119
- dict
120
-
121
- """
122
- dict_to_save = OrderedDict()
123
- dict_to_save.update({"CLASS_NAME":self.__class__.__name__})
124
- try:
125
- if self.keys() is not None:
126
- for key in self.keys():
127
- tmp1 = eval("self._%s" % (key) )
128
- if isinstance(tmp1, SynedObject):
129
- dict_to_save[key] = tmp1.to_full_dictionary()
130
- else:
131
- mylist = []
132
- mylist.append(tmp1)
133
- mylist.append(self._support_dictionary[key])
134
- dict_to_save[key] = mylist # [tmp1,self._support_dictionary[key]]
135
- except:
136
- print("** Warning: failed to load/write one or multiple items in ", self.keys())
137
-
138
- return dict_to_save
139
-
140
- def to_json(self, file_name=None):
141
- """
142
- Writes a json file with the SYNED object data.
143
-
144
- Parameters
145
- ----------
146
- file_name : str
147
- The file name
148
-
149
- Returns
150
- -------
151
- str
152
- JSON formatted str. The result of json.dumps()
153
-
154
- """
155
- dict1 = OrderedDict()
156
- dict1.update(self.to_dictionary())
157
-
158
- jsn1 = json.dumps(dict1, indent=4, separators=(',', ': '))
159
- if file_name != None:
160
- f = open(file_name,'w')
161
- f.write(jsn1)
162
- f.close()
163
- print("File written to disk: %s"%(file_name))
164
- return jsn1
165
-
166
- def info_recurrent(self, fd, prefix=" "):
167
- """
168
- Get text info of recurrent SYNED objects.
169
-
170
- Parameters
171
- ----------
172
- fd : dict
173
- The dictionary with SYNED data.
174
- prefix : str, optional
175
- Prefix to indent recursive items.
176
-
177
- Returns
178
- -------
179
- str
180
-
181
- """
182
- text = ""
183
- prefix1 = prefix
184
- for key in fd.keys():
185
- if isinstance(fd[key],OrderedDict):
186
- text += prefix1 + self.info_recurrent(fd[key], prefix=prefix1)
187
- elif isinstance(fd[key],str):
188
- text += prefix1 + "-------%s---------\n"%fd[key]
189
- elif isinstance(fd[key],list):
190
- if isinstance(fd[key][0],OrderedDict):
191
- for element in fd[key]:
192
- text += self.info_recurrent(element, prefix=prefix1)
193
- elif isinstance(fd[key][0],list):
194
- for i,element in enumerate(fd[key][0]):
195
- try:
196
- # text += "****\n"
197
- text += prefix1 + element.info()
198
- except:
199
- text += ("%s%s[%d]: %s\n" %(prefix1, key, i, repr(element))) # used for conic coefficients
200
- else:
201
- text += prefix1 + prefix1 + '%s: %s %s # %s\n' %(key, repr(fd[key][0]), fd[key][1][1], fd[key][1][0])
202
- else:
203
- pass
204
- return text
205
-
206
- def info(self):
207
- """
208
- Get text info of recurrent SYNED objects.
209
-
210
- Returns
211
- -------
212
- str
213
-
214
- """
215
- return self.info_recurrent( self.to_full_dictionary() )
216
-
217
- def set_value_from_key_name(self,key,value):
218
- """
219
- Sets a value using its key value.
220
-
221
- Parameters
222
- ----------
223
- key : str
224
- The key for the value to modify.
225
- value
226
- The new value
227
-
228
- """
229
- if key in self.keys():
230
- try:
231
- exec("self._%s = value" % (key))
232
- # print("Set variable %s to value: "%key + repr(value))
233
- except:
234
- raise ValueError("Cannot set variable %s to value: "%key + repr(value) )
235
- else:
236
- raise ValueError("Key %s not accepted by class %s"%(key,self.__class__.__name__))
237
-
238
- def get_value_from_key_name(self, key):
239
- """
240
- Gets a value using its key value.
241
-
242
- Parameters
243
- ----------
244
- key : str
245
- The key for the value to retrieve.
246
-
247
- """
248
- try:
249
- value = eval("self._%s" % (key))
250
- return value
251
- except:
252
- raise ValueError("Cannot get variable %s: "%key)
253
-
254
- def duplicate(self):
255
- """
256
- Returns a copy of the SYNED object instance.
257
-
258
- Returns
259
- -------
260
- SynedObject instance
261
- A copy of the object instance.
262
-
263
- """
264
- return copy.deepcopy(self)
1
+ import copy
2
+ from collections import OrderedDict
3
+ import pickle
4
+
5
+ import json_tricks # to save numpy arrays
6
+
7
+ # TODO: although basic functionality is implemented, the use of exec should be replace by introspection tools
8
+ class SynedObject(object):
9
+
10
+ # ---------------------------------------------------------------------------------------------------------
11
+ # This override is necessary to avoid TypeError: cannot pickle '_thread.lock' object while duplicating
12
+ # that occurs while enabling/disabling connectors
13
+ #
14
+ # When an attribute is an object that contains non pickable attributes, we make a shallow copy of it
15
+ # ---------------------------------------------------------------------------------------------------------
16
+
17
+ def __deepcopy__(self, memodict={}):
18
+ cls = self.__class__
19
+ result = cls.__new__(cls)
20
+ memodict[id(self)] = result
21
+ for k, v in self.__dict__.items():
22
+ try: setattr(result, k, copy.deepcopy(v, memodict))
23
+ except TypeError: setattr(result, k, copy.copy(v))
24
+ return result
25
+
26
+ """
27
+ This is the base object for SYNED.
28
+
29
+ It includes the methods of the common interface to allow json file input/output and info mechanism
30
+
31
+ These standard methods are:
32
+ * keys()
33
+ * to_dictionary()
34
+ * to_full_dictionary()
35
+ * to_json()
36
+ * to_hex_tring()
37
+ * from_hex_tring()
38
+ * info()
39
+ * set_value_from_key_name()
40
+ * get_value_from_key_name()
41
+
42
+ """
43
+
44
+ def _set_support_text(self, text):
45
+ ordered_support_dict = OrderedDict()
46
+ for e in text:
47
+ ordered_support_dict[e[0]] = (e[1], e[2])
48
+ self._support_dictionary = ordered_support_dict
49
+
50
+ def _add_support_text(self, text):
51
+ try:
52
+ for e in text:
53
+ self._support_dictionary[e[0]] = (e[1], e[2])
54
+ except:
55
+ self._set_support_text(text)
56
+
57
+ #
58
+ # this is the common interface to allow json file input/output and info mechanism
59
+ #
60
+ # standard methods are:
61
+ # keys
62
+ # to_dictionary
63
+ # to_full_dictionary
64
+ # to_json
65
+ # info
66
+ # set_value_from_key_name
67
+ # get_value_from_key_name
68
+ #
69
+ def keys(self):
70
+ """
71
+ Returns the keys of the supporting doctionary.
72
+ Returns
73
+ -------
74
+ list
75
+ A list of keys.
76
+
77
+ """
78
+ try:
79
+ return self._support_dictionary.keys()
80
+ except:
81
+ return None
82
+
83
+ def to_dictionary(self):
84
+ """
85
+ Returns a dictionary with the object fields.
86
+
87
+ Some dictionary keys may contain SYNED instances. Use to_full_dictionary to recurrently expand these objects
88
+ in their basic ingredients.
89
+
90
+ Returns
91
+ -------
92
+ dict
93
+ A dictionary with the data.
94
+
95
+ """
96
+ dict_to_save = OrderedDict()
97
+ dict_to_save.update({"CLASS_NAME":self.__class__.__name__})
98
+
99
+ try:
100
+ if self.keys() is not None:
101
+ for key in self.keys():
102
+ tmp1 = eval("self._%s" % (key) )
103
+ if isinstance(tmp1,SynedObject):
104
+ dict_to_save[key] = tmp1.to_dictionary()
105
+ else:
106
+ dict_to_save[key] = tmp1
107
+ except:
108
+ pass
109
+
110
+ return dict_to_save
111
+
112
+ def to_full_dictionary(self):
113
+ """
114
+ Returns a dictionary with the object fields, including other syned objects embedded or list of elements.
115
+
116
+ The "full" means that the SYNED instances found are recurrently expanded in their basic ingredients.
117
+
118
+ Returns
119
+ -------
120
+ dict
121
+
122
+ """
123
+ dict_to_save = OrderedDict()
124
+ dict_to_save.update({"CLASS_NAME":self.__class__.__name__})
125
+ try:
126
+ if self.keys() is not None:
127
+ for key in self.keys():
128
+ tmp1 = eval("self._%s" % (key) )
129
+ if isinstance(tmp1, SynedObject):
130
+ dict_to_save[key] = tmp1.to_full_dictionary()
131
+ else:
132
+ mylist = []
133
+ mylist.append(tmp1)
134
+ mylist.append(self._support_dictionary[key])
135
+ dict_to_save[key] = mylist # [tmp1,self._support_dictionary[key]]
136
+ except:
137
+ print("** Warning: failed to load/write one or multiple items in ", self.keys())
138
+
139
+ return dict_to_save
140
+
141
+ def to_json(self, file_name=None):
142
+ """
143
+ Writes a json file with the SYNED object data.
144
+
145
+ Parameters
146
+ ----------
147
+ file_name : str
148
+ The file name
149
+
150
+ Returns
151
+ -------
152
+ str
153
+ JSON formatted str. The result of json.dumps()
154
+
155
+ """
156
+ dict1 = OrderedDict()
157
+ dict1.update(self.to_dictionary())
158
+
159
+ jsn1 = json_tricks.dumps(dict1, indent=4, separators=(',', ': '))
160
+ if file_name != None:
161
+ f = open(file_name,'w')
162
+ f.write(jsn1)
163
+ f.close()
164
+ print("File written to disk: %s"%(file_name))
165
+ return jsn1
166
+
167
+ def to_hex_tring(self):
168
+ return pickle.dumps(self).hex()
169
+
170
+ @classmethod
171
+ def from_hex_tring(cls, hex_string):
172
+ return pickle.loads(bytes.fromhex(hex_string))
173
+
174
+
175
+ def info_recurrent(self, fd, prefix=" "):
176
+ """
177
+ Get text info of recurrent SYNED objects.
178
+
179
+ Parameters
180
+ ----------
181
+ fd : dict
182
+ The dictionary with SYNED data.
183
+ prefix : str, optional
184
+ Prefix to indent recursive items.
185
+
186
+ Returns
187
+ -------
188
+ str
189
+
190
+ """
191
+ text = ""
192
+ prefix1 = prefix
193
+ for key in fd.keys():
194
+ if isinstance(fd[key],OrderedDict):
195
+ text += prefix1 + self.info_recurrent(fd[key], prefix=prefix1)
196
+ elif isinstance(fd[key],str):
197
+ text += prefix1 + "-------%s---------\n"%fd[key]
198
+ elif isinstance(fd[key],list):
199
+ if isinstance(fd[key][0],OrderedDict):
200
+ for element in fd[key]:
201
+ text += self.info_recurrent(element, prefix=prefix1)
202
+ elif isinstance(fd[key][0],list):
203
+ for i,element in enumerate(fd[key][0]):
204
+ try:
205
+ # text += "****\n"
206
+ text += prefix1 + element.info()
207
+ except:
208
+ text += ("%s%s[%d]: %s\n" %(prefix1, key, i, repr(element))) # used for conic coefficients
209
+ else:
210
+ text += prefix1 + prefix1 + '%s: %s %s # %s\n' %(key, repr(fd[key][0]), fd[key][1][1], fd[key][1][0])
211
+ else:
212
+ pass
213
+ return text
214
+
215
+ def info(self):
216
+ """
217
+ Get text info of recurrent SYNED objects.
218
+
219
+ Returns
220
+ -------
221
+ str
222
+
223
+ """
224
+ return self.info_recurrent( self.to_full_dictionary() )
225
+
226
+ def set_value_from_key_name(self,key,value):
227
+ """
228
+ Sets a value using its key value.
229
+
230
+ Parameters
231
+ ----------
232
+ key : str
233
+ The key for the value to modify.
234
+ value
235
+ The new value
236
+
237
+ """
238
+ if key in self.keys():
239
+ try:
240
+ exec("self._%s = value" % (key))
241
+ # print("Set variable %s to value: "%key + repr(value))
242
+ except:
243
+ raise ValueError("Cannot set variable %s to value: "%key + repr(value) )
244
+ else:
245
+ raise ValueError("Key %s not accepted by class %s"%(key,self.__class__.__name__))
246
+
247
+ def get_value_from_key_name(self, key):
248
+ """
249
+ Gets a value using its key value.
250
+
251
+ Parameters
252
+ ----------
253
+ key : str
254
+ The key for the value to retrieve.
255
+
256
+ """
257
+ try:
258
+ value = eval("self._%s" % (key))
259
+ return value
260
+ except:
261
+ raise ValueError("Cannot get variable %s: "%key)
262
+
263
+ def duplicate(self):
264
+ """
265
+ Returns a copy of the SYNED object instance.
266
+
267
+ Returns
268
+ -------
269
+ SynedObject instance
270
+ A copy of the object instance.
271
+
272
+ """
273
+ return copy.deepcopy(self)
syned/util/__init__.py CHANGED
@@ -1,22 +1,22 @@
1
- import functools
2
- import warnings
3
-
4
- def deprecated(reason: str = ""):
5
- """
6
- Decorator to mark functions as deprecated.
7
- It will result in a warning being emitted when the function is used.
8
- """
9
- def decorator(func):
10
- msg = f"The function `{func.__name__}` is deprecated."
11
- if reason:
12
- msg += f" {reason}"
13
-
14
- @functools.wraps(func)
15
- def wrapper(*args, **kwargs):
16
- warnings.simplefilter("always", DeprecationWarning) # show even if filtered
17
- warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
18
- warnings.simplefilter("default", DeprecationWarning) # reset filter
19
- return func(*args, **kwargs)
20
- return wrapper
21
-
1
+ import functools
2
+ import warnings
3
+
4
+ def deprecated(reason: str = ""):
5
+ """
6
+ Decorator to mark functions as deprecated.
7
+ It will result in a warning being emitted when the function is used.
8
+ """
9
+ def decorator(func):
10
+ msg = f"The function `{func.__name__}` is deprecated."
11
+ if reason:
12
+ msg += f" {reason}"
13
+
14
+ @functools.wraps(func)
15
+ def wrapper(*args, **kwargs):
16
+ warnings.simplefilter("always", DeprecationWarning) # show even if filtered
17
+ warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
18
+ warnings.simplefilter("default", DeprecationWarning) # reset filter
19
+ return func(*args, **kwargs)
20
+ return wrapper
21
+
22
22
  return decorator