temscript 2.0.1__tar.gz → 2.2.0__tar.gz

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 (44) hide show
  1. {temscript-2.0.1/temscript.egg-info → temscript-2.2.0}/PKG-INFO +17 -3
  2. {temscript-2.0.1 → temscript-2.2.0}/docs/changelog.rst +22 -0
  3. {temscript-2.0.1 → temscript-2.2.0}/docs/conf.py +1 -1
  4. {temscript-2.0.1 → temscript-2.2.0}/docs/instrument.rst +7 -0
  5. {temscript-2.0.1 → temscript-2.2.0}/docs/restrictions.rst +4 -0
  6. temscript-2.2.0/scripts/test_com.py +34 -0
  7. {temscript-2.0.1 → temscript-2.2.0}/scripts/test_microscope.py +2 -0
  8. {temscript-2.0.1 → temscript-2.2.0}/setup.py +1 -1
  9. {temscript-2.0.1 → temscript-2.2.0}/temscript/_com.py +24 -1
  10. {temscript-2.0.1 → temscript-2.2.0}/temscript/_instrument_com.py +1 -1
  11. {temscript-2.0.1 → temscript-2.2.0}/temscript/base_microscope.py +60 -8
  12. {temscript-2.0.1 → temscript-2.2.0}/temscript/microscope.py +31 -4
  13. {temscript-2.0.1 → temscript-2.2.0}/temscript/null_microscope.py +0 -4
  14. {temscript-2.0.1 → temscript-2.2.0}/temscript/remote_microscope.py +5 -2
  15. {temscript-2.0.1 → temscript-2.2.0}/temscript/server.py +14 -14
  16. temscript-2.2.0/temscript/version.py +1 -0
  17. {temscript-2.0.1 → temscript-2.2.0/temscript.egg-info}/PKG-INFO +17 -3
  18. {temscript-2.0.1 → temscript-2.2.0}/temscript.egg-info/SOURCES.txt +1 -0
  19. temscript-2.0.1/temscript/version.py +0 -1
  20. {temscript-2.0.1 → temscript-2.2.0}/LICENSE +0 -0
  21. {temscript-2.0.1 → temscript-2.2.0}/MANIFEST.in +0 -0
  22. {temscript-2.0.1 → temscript-2.2.0}/README.md +0 -0
  23. {temscript-2.0.1 → temscript-2.2.0}/docs/Makefile +0 -0
  24. {temscript-2.0.1 → temscript-2.2.0}/docs/about.rst +0 -0
  25. {temscript-2.0.1 → temscript-2.2.0}/docs/index.rst +0 -0
  26. {temscript-2.0.1 → temscript-2.2.0}/docs/make.bat +0 -0
  27. {temscript-2.0.1 → temscript-2.2.0}/docs/microscope.rst +0 -0
  28. {temscript-2.0.1 → temscript-2.2.0}/docs/requirements.txt +0 -0
  29. {temscript-2.0.1 → temscript-2.2.0}/docs/server.rst +0 -0
  30. {temscript-2.0.1 → temscript-2.2.0}/pyproject.toml +0 -0
  31. {temscript-2.0.1 → temscript-2.2.0}/scripts/run_null_server.py +0 -0
  32. {temscript-2.0.1 → temscript-2.2.0}/scripts/test_camera_acquisition.py +0 -0
  33. {temscript-2.0.1 → temscript-2.2.0}/scripts/test_instrument.py +0 -0
  34. {temscript-2.0.1 → temscript-2.2.0}/scripts/test_json_encoder.py +0 -0
  35. {temscript-2.0.1 → temscript-2.2.0}/setup.cfg +0 -0
  36. {temscript-2.0.1 → temscript-2.2.0}/temscript/__init__.py +0 -0
  37. {temscript-2.0.1 → temscript-2.2.0}/temscript/_instrument_stubs.py +0 -0
  38. {temscript-2.0.1 → temscript-2.2.0}/temscript/enums.py +0 -0
  39. {temscript-2.0.1 → temscript-2.2.0}/temscript/instrument.py +0 -0
  40. {temscript-2.0.1 → temscript-2.2.0}/temscript/marshall.py +0 -0
  41. {temscript-2.0.1 → temscript-2.2.0}/temscript.egg-info/dependency_links.txt +0 -0
  42. {temscript-2.0.1 → temscript-2.2.0}/temscript.egg-info/entry_points.txt +0 -0
  43. {temscript-2.0.1 → temscript-2.2.0}/temscript.egg-info/requires.txt +0 -0
  44. {temscript-2.0.1 → temscript-2.2.0}/temscript.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: temscript
3
- Version: 2.0.1
4
- Summary: TEM Scripting adapter for FEI microscopes
3
+ Version: 2.2.0
4
+ Summary: TEM Scripting adapter for TFS/FEI transmission electron microscopes
5
5
  Home-page: https://github.com/niermann/temscript
6
6
  Author: Tore Niermann
7
7
  Author-email: tore.niermann@tu-berlin.de
@@ -21,6 +21,20 @@ Classifier: Operating System :: OS Independent
21
21
  Requires-Python: >=3.4
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
+ Requires-Dist: numpy
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: platform
34
+ Dynamic: project-url
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
24
38
 
25
39
  # About
26
40
 
@@ -1,6 +1,28 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ Version 2.2.0
5
+ ^^^^^^^^^^^^^
6
+
7
+ * Added get_instrument_id(), which returns the microscope's serial number (D-number, without "D" prefix) from the
8
+ Windows registry (or an empty string if unavailable).
9
+ * Added get_computer_name(), which returns the hostname of the microscope computer.
10
+ * Deprecated get_microscope_id() as the term is ambiguous, use get_computer_name() or get_instrument_id() instead.
11
+ * Added "instrument_id" and "computer_name" entries to the dictionary returned by get_state(). The "microscope_id"
12
+ entry is deprecated and will be removed in future versions.
13
+
14
+ Version 2.1.1
15
+ ^^^^^^^^^^^^^
16
+
17
+ * Fixed error handling in server
18
+ * Don't throw error for get_stage_holder(), if no holder inserted
19
+
20
+ Version 2.1.0
21
+ ^^^^^^^^^^^^^
22
+
23
+ * Changed default apartment model to COINIT_APARTMENTTHREADED to increase compatibility with comtypes
24
+ * COM initialization respects setting from sys.coinit_flags
25
+
4
26
  Version 2.0.1
5
27
  ^^^^^^^^^^^^^
6
28
 
@@ -125,7 +125,7 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
125
125
  # Add any paths that contain custom static files (such as style sheets) here,
126
126
  # relative to this directory. They are copied after the builtin static files,
127
127
  # so a file named "default.css" will overwrite the builtin "default.css".
128
- html_static_path = ['_static']
128
+ #html_static_path = ['_static']
129
129
 
130
130
  # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
131
131
  # using the given strftime format.
@@ -13,6 +13,13 @@ The interface is described in detail in the scripting manual of your microscope
13
13
  The manual is your ultimate reference, this documentation will only describe the
14
14
  python wrapper to the COM interface.
15
15
 
16
+ The COM apartment model will automatically be initialized as ``COINIT_APARTMENTTHREADED``
17
+ (this changed in Version 2.1.0, it was ``COINIT_MULTITHREADED`` before). However, if the
18
+ apartment model was already initialized as ``COINIT_MULTITHREADED`` before `temscript`
19
+ was imported, `temscript` will also work. If you want a specific apartment model, set the
20
+ variable ``sys.coinit_flags`` before importing `temscript`.
21
+
22
+
16
23
  Enumerations
17
24
  ^^^^^^^^^^^^
18
25
 
@@ -8,6 +8,10 @@ to this scripting interface, thus these issues also occur using `temscript`. As
8
8
  with the scripting interfaces by FEI or Thermo Fisher Scientific themself, known issues are listed here for the user's
9
9
  reference.
10
10
 
11
+ * The standard scripting interface does not expose the microscope's serial number (D-number).
12
+ ``get_instrument_id()`` reads the ``Instrument Key`` DWORD from ``HKEY_LOCAL_MACHINE\SOFTWARE\FEI\Configuration``
13
+ instead (verified on Titan 1.1), returning the number as decimal string without "D" prefix. If the value is
14
+ missing, inaccessible, not a DWORD, or zero, an empty string is returned.
11
15
  * Changing the projection mode from IMAGING to DIFFRACTION and back again changes the magnification in imaging
12
16
  mode (Titan 1.1).
13
17
  * :attr:`Projection.Magnification` does not return the actual magnification, but always 0.0 (Titan 1.1)
@@ -0,0 +1,34 @@
1
+ from temscript._com import CLSCTX_ALL, IUnknown, co_create_instance
2
+ from temscript._instrument_com import LongProperty, ObjectProperty
3
+ from uuid import UUID
4
+
5
+ # This test requires the TemscriptMockObject.dll to be registered
6
+ # Use "regsvr32.exe TemscriptMockObject.dll" with admin privileges to register it, before running this script
7
+ CLSID_MockObject = UUID('e5766dfa-303e-48a9-983e-352fa4a5a408')
8
+
9
+ class IChildObject(IUnknown):
10
+ IID = UUID('bbbd2968-4b93-49a9-b1ae-16d1d6b563eb')
11
+
12
+ value = LongProperty(get_index=3, put_index=4)
13
+
14
+
15
+ class IMockObject(IUnknown):
16
+ IID = UUID('bbbd2968-4b93-49a9-b1ae-16d1d6b563eb')
17
+
18
+ value = LongProperty(get_index=3, put_index=4)
19
+ child = ObjectProperty(IChildObject, get_index=5)
20
+
21
+
22
+ def test_mock_object():
23
+ obj = co_create_instance(CLSID_MockObject, CLSCTX_ALL, IMockObject)
24
+
25
+ obj.value = 123
26
+ assert obj.value == 123
27
+
28
+ child = obj.child
29
+ child.value = 321
30
+ assert child.value == 321
31
+ assert obj.value == 123
32
+
33
+
34
+ test_mock_object()
@@ -31,6 +31,8 @@ else:
31
31
 
32
32
  print("Microscope.get_family():", microscope.get_family())
33
33
  print("Microscope.get_microscope_id():", microscope.get_microscope_id())
34
+ print("Microscope.get_computer_name():", microscope.get_computer_name())
35
+ print("Microscope.get_instrument_id():", microscope.get_instrument_id())
34
36
  print("Microscope.get_version():", microscope.get_version())
35
37
  print("Microscope.get_voltage():", microscope.get_voltage())
36
38
  print("Microscope.get_vacuum():", microscope.get_vacuum())
@@ -14,7 +14,7 @@ with open("temscript/version.py") as fp:
14
14
 
15
15
  setup(name='temscript',
16
16
  version=__version__,
17
- description='TEM Scripting adapter for FEI microscopes',
17
+ description='TEM Scripting adapter for TFS/FEI transmission electron microscopes',
18
18
  author='Tore Niermann',
19
19
  author_email='tore.niermann@tu-berlin.de',
20
20
  long_description=long_description,
@@ -6,6 +6,7 @@ __all__ = 'UUID', 'CLSCTX_ALL', 'IUnknown', 'co_create_instance', 'SafeArray', '
6
6
 
7
7
  # COM constants
8
8
  COINIT_MULTITHREADED = 0
9
+ COINIT_APARTMENTTHREADED = 2
9
10
  CLSCTX_ALL = 0x17
10
11
 
11
12
 
@@ -370,5 +371,27 @@ class SafeArray:
370
371
 
371
372
 
372
373
  _ole32 = ctypes.oledll.ole32
373
- _ole32.CoInitializeEx(None, ctypes.c_int(COINIT_MULTITHREADED))
374
374
  _oleauto = ctypes.windll.oleaut32
375
+
376
+ def initialize_com(flags=None):
377
+ RPC_E_CHANGED_MODE = -2147417850
378
+
379
+ # The comtypes package allows to specify the apartment model by
380
+ # setting sys.coinit_flags in advance. We copy this behavior.
381
+ if flags is None:
382
+ import sys
383
+ flags = getattr(sys, "coinit_flags", None)
384
+
385
+ if flags is None:
386
+ # If we don't have explicit flags, try STA first and fall back to MTA
387
+ # if COM is already initialized to MTA.
388
+ try:
389
+ _ole32.CoInitializeEx(None, ctypes.c_int(COINIT_APARTMENTTHREADED))
390
+ except WindowsError as exc:
391
+ if exc.winerror == RPC_E_CHANGED_MODE:
392
+ _ole32.CoInitializeEx(None, ctypes.c_int(COINIT_MULTITHREADED))
393
+ else:
394
+ # Otherwise, use the apartment model we got
395
+ _ole32.CoInitializeEx(None, flags)
396
+
397
+ initialize_com()
@@ -28,7 +28,7 @@ class LongProperty(BaseProperty):
28
28
  if self._get_index is None:
29
29
  raise AttributeError("Attribute %s is not readable" % self._name)
30
30
  result = ctypes.c_long(-1)
31
- prototype = ctypes.WINFUNCTYPE(ctypes.HRESULT, ctypes.c_void_p)(self._get_index, "get_property")
31
+ prototype = ctypes.WINFUNCTYPE(ctypes.HRESULT, ctypes.POINTER(ctypes.c_long))(self._get_index, "get_property")
32
32
  prototype(obj.get(), ctypes.byref(result))
33
33
  return result.value
34
34
 
@@ -84,14 +84,48 @@ class BaseMicroscope(ABC):
84
84
  """Return product family (see :class:`ProductFamily` for values): "TITAN", "TECNAI", ..."""
85
85
  raise NotImplementedError
86
86
 
87
- @abstractmethod
88
87
  def get_microscope_id(self):
89
88
  """
90
- Return microscope ID.
89
+ Return hostname of microscope's computer.
91
90
 
92
- There is no way to read this via the scripting adapter directly, thus this method uses hostname instead.
91
+ .. deprecated:: 2.2.0
92
+ The term "microscope ID" is ambiguous. FEI/TFS instruments identify themselves by the computer name
93
+ and the instrument ID (as also stored in Velox metadata), use :meth:`get_computer_name` or
94
+ :meth:`get_instrument_id` instead.
93
95
  """
94
- raise NotImplementedError
96
+ import warnings
97
+ warnings.warn("Microscope.get_microscope_id() is deprecated. "
98
+ "Use get_computer_name() and/or get_instrument_id() instead.",
99
+ category=DeprecationWarning, stacklevel=2)
100
+ return self.get_computer_name()
101
+
102
+ def get_computer_name(self):
103
+ """
104
+ Return name (hostname) of the microscope computer.
105
+
106
+ This corresponds to the computer name stored by FEI/TFS software, e.g. in Velox metadata.
107
+
108
+ .. versionadded:: 2.2.0
109
+ """
110
+ import socket
111
+ return socket.gethostname()
112
+
113
+ def get_instrument_id(self):
114
+ """
115
+ Return serial number of the microscope as string of decimal digits (without the "D" prefix,
116
+ e.g. "1234" for D1234).
117
+
118
+ :class:`Microscope` reads the ``Instrument Key`` DWORD from
119
+ ``HKEY_LOCAL_MACHINE\\SOFTWARE\\FEI\\Configuration`` in the Windows registry. If the serial number
120
+ is not available, an empty string is returned. See :ref:`restrictions` for details.
121
+
122
+ This corresponds to the instrument ID stored by FEI/TFS software, e.g. in Velox metadata.
123
+
124
+ The default implementation returns an empty string.
125
+
126
+ .. versionadded:: 2.2.0
127
+ """
128
+ return ""
95
129
 
96
130
  @abstractmethod
97
131
  def get_version(self):
@@ -641,7 +675,11 @@ class BaseMicroscope(ABC):
641
675
  def get_indicated_camera_length(self):
642
676
  """
643
677
  Return (indicated) camera length in meters in diffraction modes.
644
- If microscope is in imaging mode, 0 is returned.
678
+
679
+ .. note::
680
+ The scripting manual states, that this function always returns 0,
681
+ if microscope is in imaging mode. In STEM mode this
682
+ function works reportedly nevertheless.
645
683
 
646
684
  .. versionadded:: 1.0.9
647
685
  """
@@ -651,7 +689,11 @@ class BaseMicroscope(ABC):
651
689
  def get_indicated_magnification(self):
652
690
  """
653
691
  Return (indicated) magnification in imaging modes.
654
- If microscope is in diffraction mode, 0 is returned.
692
+
693
+ .. note::
694
+ The scripting manual states, that this function always returns 0,
695
+ if microscope is in diffraction mode. In STEM mode this
696
+ function works reportedly nevertheless.
655
697
 
656
698
  .. note::
657
699
  On Titan 1.1 software this method returns 0.0 regardless of used mode. See :ref:`restrictions`.
@@ -1123,10 +1165,19 @@ class BaseMicroscope(ABC):
1123
1165
 
1124
1166
  .. versionchanged:: 2.0
1125
1167
  The method was renamed from get_optics_state() to get_state()
1168
+
1169
+ .. versionchanged:: 2.2.0
1170
+ Added "instrument_id" and "computer_name" entries.
1171
+
1172
+ .. deprecated:: 2.2.0
1173
+ The "microscope_id" entry is deprecated and will be removed in future versions. It contains the
1174
+ same value as "computer_name", use that entry instead. See :meth:`get_microscope_id`.
1126
1175
  """
1127
1176
  state = {
1128
1177
  "family": self.get_family(),
1129
- "microscope_id": self.get_microscope_id(),
1178
+ "microscope_id": self.get_computer_name(),
1179
+ "instrument_id": self.get_instrument_id(),
1180
+ "computer_name": self.get_computer_name(),
1130
1181
  "temscript_version": self.get_version(),
1131
1182
  "voltage(kV)": self.get_voltage(),
1132
1183
  "stage_holder": self.get_stage_holder(),
@@ -1174,5 +1225,6 @@ class BaseMicroscope(ABC):
1174
1225
  use :meth:`get_state` instead.
1175
1226
  """
1176
1227
  import warnings
1177
- warnings.warn("Microscope.get_optics_state() is deprecated. Use get_state() instead.", DeprecationWarning)
1228
+ warnings.warn("Microscope.get_optics_state() is deprecated. Use get_state() instead.",
1229
+ category=DeprecationWarning, stacklevel=2)
1178
1230
  return self.get_state()
@@ -1,3 +1,4 @@
1
+ import functools
1
2
  import math
2
3
 
3
4
  from temscript.base_microscope import set_enum_attr_from_dict, set_attr_from_dict
@@ -7,6 +8,27 @@ from .instrument import CCDCamera, GetInstrument, STEMDetector
7
8
  from .enums import *
8
9
 
9
10
 
11
+ # Computer name and instrument ID are properties of the machine, thus cached at module level
12
+ # (and not per instance, which would keep instances alive).
13
+ @functools.lru_cache(maxsize=None)
14
+ def _get_computer_name():
15
+ import socket
16
+ return socket.gethostname()
17
+
18
+
19
+ @functools.lru_cache(maxsize=None)
20
+ def _get_instrument_id():
21
+ import winreg
22
+ try:
23
+ with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\FEI\Configuration") as key:
24
+ value, value_type = winreg.QueryValueEx(key, "Instrument Key")
25
+ if value_type == winreg.REG_DWORD and value > 0:
26
+ return str(value)
27
+ except OSError:
28
+ pass # Missing key/value or access denied.
29
+ return ""
30
+
31
+
10
32
  class Microscope(BaseMicroscope):
11
33
  """
12
34
  Hich level interface to local microscope.
@@ -38,9 +60,11 @@ class Microscope(BaseMicroscope):
38
60
  def get_family(self):
39
61
  return ProductFamily(self._family).name
40
62
 
41
- def get_microscope_id(self):
42
- import socket
43
- return socket.gethostname()
63
+ def get_computer_name(self):
64
+ return _get_computer_name()
65
+
66
+ def get_instrument_id(self):
67
+ return _get_instrument_id()
44
68
 
45
69
  def get_version(self):
46
70
  from .version import __version__
@@ -79,7 +103,10 @@ class Microscope(BaseMicroscope):
79
103
  self._tem_vacuum.ColumnValvesOpen = state
80
104
 
81
105
  def get_stage_holder(self):
82
- return self._tem_stage.Holder.name
106
+ try:
107
+ return self._tem_stage.Holder.name
108
+ except OSError:
109
+ return ""
83
110
 
84
111
  def get_stage_status(self):
85
112
  return self._tem_stage.Status.name
@@ -122,10 +122,6 @@ class NullMicroscope(BaseMicroscope):
122
122
  def get_family(self):
123
123
  return "NULL"
124
124
 
125
- def get_microscope_id(self):
126
- import socket
127
- return socket.gethostname()
128
-
129
125
  def get_version(self):
130
126
  from .version import __version__
131
127
  return __version__
@@ -130,8 +130,11 @@ class RemoteMicroscope(BaseMicroscope):
130
130
  def get_family(self):
131
131
  return self._request("GET", "/v1/family")[1]
132
132
 
133
- def get_microscope_id(self):
134
- return self._request("GET", "/v1/microscope_id")[1]
133
+ def get_computer_name(self):
134
+ return self._request("GET", "/v1/computer_name")[1]
135
+
136
+ def get_instrument_id(self):
137
+ return self._request("GET", "/v1/instrument_id")[1]
135
138
 
136
139
  def get_version(self):
137
140
  return self._request("GET", "/v1/version")[1]
@@ -8,15 +8,15 @@ from .marshall import ExtendedJsonEncoder, gzip_encode, MIME_TYPE_PICKLE, MIME_T
8
8
 
9
9
 
10
10
  class MicroscopeHandler(BaseHTTPRequestHandler):
11
- GET_V1_FORWARD = ("family", "microscope_id", "version", "voltage", "vacuum", "stage_holder",
12
- "stage_status", "stage_position", "stage_limits", "detectors", "cameras", "stem_detectors",
13
- "stem_acquisition_param", "image_shift", "beam_shift", "beam_tilt", "projection_sub_mode",
14
- "projection_mode", "projection_mode_string", "magnification_index", "indicated_camera_length",
15
- "indicated_magnification", "defocus", "objective_excitation", "intensity", "objective_stigmator",
16
- "condenser_stigmator", "diffraction_shift", "screen_current", "screen_position",
17
- "illumination_mode", "condenser_mode", "illuminated_area", "probe_defocus", "convergence_angle",
18
- "stem_magnification", "stem_rotation", "spot_size_index", "dark_field_mode", "beam_blanked",
19
- "instrument_mode", 'optics_state', 'state', 'column_valves_open')
11
+ GET_V1_FORWARD = ("family", "microscope_id", "instrument_id", "computer_name", "version", "voltage", "vacuum",
12
+ "stage_holder", "stage_status", "stage_position", "stage_limits", "detectors", "cameras",
13
+ "stem_detectors", "stem_acquisition_param", "image_shift", "beam_shift", "beam_tilt",
14
+ "projection_sub_mode", "projection_mode", "projection_mode_string", "magnification_index",
15
+ "indicated_camera_length", "indicated_magnification", "defocus", "objective_excitation",
16
+ "intensity", "objective_stigmator", "condenser_stigmator", "diffraction_shift", "screen_current",
17
+ "screen_position", "illumination_mode", "condenser_mode", "illuminated_area", "probe_defocus",
18
+ "convergence_angle", "stem_magnification", "stem_rotation", "spot_size_index", "dark_field_mode",
19
+ "beam_blanked", "instrument_mode", 'optics_state', 'state', 'column_valves_open')
20
20
 
21
21
  PUT_V1_FORWARD = ("image_shift", "beam_shift", "beam_tilt", "projection_mode", "magnification_index",
22
22
  "defocus", "intensity", "diffraction_shift", "objective_stigmator", "condenser_stigmator",
@@ -58,7 +58,7 @@ class MicroscopeHandler(BaseHTTPRequestHandler):
58
58
  else:
59
59
  content_encoding = None
60
60
  except Exception as exc:
61
- self.log_error("Exception raised during encoding of response: %s" % repr(exc))
61
+ self.log_error("Exception raised during encoding of response: %s", repr(exc))
62
62
  self.send_error(500, "Error handling request '%s': %s" % (self.path, str(exc)))
63
63
  else:
64
64
  self.send_response(200)
@@ -146,10 +146,10 @@ class MicroscopeHandler(BaseHTTPRequestHandler):
146
146
  else:
147
147
  raise KeyError('Unknown API version: %s' % self.path)
148
148
  except KeyError as exc:
149
- self.log_error("KeyError raised during handling of GET request '%s': %s" % (self.path, repr(exc)))
149
+ self.log_error("KeyError raised during handling of GET request '%s': %s", self.path, repr(exc))
150
150
  self.send_error(404, str(exc))
151
151
  except Exception as exc:
152
- self.log_error("Exception raised during handling of GET request '%s': %s" % (self.path, repr(exc)))
152
+ self.log_error("Exception raised during handling of GET request '%s': %s", self.path, repr(exc))
153
153
  self.send_error(500, "Error handling request '%s': %s" % (self.path, str(exc)))
154
154
  else:
155
155
  self.build_response(response)
@@ -163,10 +163,10 @@ class MicroscopeHandler(BaseHTTPRequestHandler):
163
163
  else:
164
164
  raise KeyError('Unknown API version: %s' % self.path)
165
165
  except KeyError as exc:
166
- self.log_error("KeyError raised during handling of GET request '%s': %s" % (self.path, repr(exc)))
166
+ self.log_error("KeyError raised during handling of GET request '%s': %s" , self.path, repr(exc))
167
167
  self.send_error(404, str(exc))
168
168
  except Exception as exc:
169
- self.log_error("Exception raised during handling of GET request '%s': %s" % (self.path, repr(exc)))
169
+ self.log_error("Exception raised during handling of GET request '%s': %s" , self.path, repr(exc))
170
170
  self.send_error(500, "Error handling request '%s': %s" % (self.path, str(exc)))
171
171
  else:
172
172
  self.build_response(response)
@@ -0,0 +1 @@
1
+ __version__ = '2.2.0'
@@ -1,7 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: temscript
3
- Version: 2.0.1
4
- Summary: TEM Scripting adapter for FEI microscopes
3
+ Version: 2.2.0
4
+ Summary: TEM Scripting adapter for TFS/FEI transmission electron microscopes
5
5
  Home-page: https://github.com/niermann/temscript
6
6
  Author: Tore Niermann
7
7
  Author-email: tore.niermann@tu-berlin.de
@@ -21,6 +21,20 @@ Classifier: Operating System :: OS Independent
21
21
  Requires-Python: >=3.4
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
+ Requires-Dist: numpy
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: platform
34
+ Dynamic: project-url
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
24
38
 
25
39
  # About
26
40
 
@@ -16,6 +16,7 @@ docs/restrictions.rst
16
16
  docs/server.rst
17
17
  scripts/run_null_server.py
18
18
  scripts/test_camera_acquisition.py
19
+ scripts/test_com.py
19
20
  scripts/test_instrument.py
20
21
  scripts/test_json_encoder.py
21
22
  scripts/test_microscope.py
@@ -1 +0,0 @@
1
- __version__ = '2.0.1'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes