nmixstudio 1.0.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.
- nmixstudio-1.0.0/MANIFEST.in +3 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiContainer/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiContainer/container.py +108 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiContainer/containerBuilder.py +40 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiContainer/enums.py +26 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiFrame/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiFrame/frame.py +72 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiFrame/frameChannels.py +79 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiImage/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiImage/image.py +89 -0
- nmixstudio-1.0.0/NMIXStudio/Container/NmiImage/imageBuilder.py +55 -0
- nmixstudio-1.0.0/NMIXStudio/Container/__init__.py +3 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/Devices/AndorCamera.py +109 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/Devices/Thorlabs_SPCM50.py +440 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/Devices/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/Devices/externalTest.py +14 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/Devices/utils.py +6 -0
- nmixstudio-1.0.0/NMIXStudio/ExternalDevices/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/NMIImporter/BuiltInImporter.py +10 -0
- nmixstudio-1.0.0/NMIXStudio/NMIImporter/Decarators.py +27 -0
- nmixstudio-1.0.0/NMIXStudio/NMIImporter/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/ApproachController.py +222 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/AutoTuneController.py +402 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/BiasController.py +106 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/HallCardController.py +268 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/OptionsController.py +132 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/PIDController.py +182 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/PhotoDiodeController.py +172 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/ScanController.py +405 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/ScannedImagesController.py +95 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/StatusController.py +43 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/SystemReadingsController.py +39 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/WindowController.py +106 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/XYOffsetController.py +158 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/Controllers/__init__.py +6 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/CustomScanner.py +127 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/DeviceManager.py +85 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/Managers/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/NMIManager/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/Plots/ContainerPlot/ContainerPlotManager.py +174 -0
- nmixstudio-1.0.0/NMIXStudio/Plots/ContainerPlot/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/Plots/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/RequestManager/NMICommand.py +75 -0
- nmixstudio-1.0.0/NMIXStudio/RequestManager/NMIEndpoint.py +57 -0
- nmixstudio-1.0.0/NMIXStudio/RequestManager/__init__.py +2 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/Approach.py +66 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/AutoTune.py +97 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/HallCard.py +70 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/Options.py +43 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/PhotoDiode.py +53 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/Pid.py +48 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/Scan.py +95 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/ScanCustom.py +13 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/ScannedImages.py +28 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/Status.py +20 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/SystemReadings.py +18 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/VBias.py +45 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/WindowControl.py +42 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Basics/XYOffset.py +41 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Experiments/CustomScan_ExternalDevice.py +58 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Experiments/NMIXStudio_AutoTuneExample.ipynb +328 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Experiments/NMIXStudio_ScanExample.ipynb +322 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/Experiments/logFile_API.log +874 -0
- nmixstudio-1.0.0/NMIXStudio/Samples/__pycache__/__init__.cpython-311.pyc +0 -0
- nmixstudio-1.0.0/NMIXStudio/Utils/__init__.py +1 -0
- nmixstudio-1.0.0/NMIXStudio/Utils/utils.py +42 -0
- nmixstudio-1.0.0/NMIXStudio/__init__.py +45 -0
- nmixstudio-1.0.0/NMIXStudio/_version.py +1 -0
- nmixstudio-1.0.0/PKG-INFO +79 -0
- nmixstudio-1.0.0/README.md +68 -0
- nmixstudio-1.0.0/nmixstudio.egg-info/PKG-INFO +79 -0
- nmixstudio-1.0.0/nmixstudio.egg-info/SOURCES.txt +76 -0
- nmixstudio-1.0.0/nmixstudio.egg-info/dependency_links.txt +1 -0
- nmixstudio-1.0.0/nmixstudio.egg-info/requires.txt +20 -0
- nmixstudio-1.0.0/nmixstudio.egg-info/top_level.txt +1 -0
- nmixstudio-1.0.0/pyproject.toml +0 -0
- nmixstudio-1.0.0/setup.cfg +4 -0
- nmixstudio-1.0.0/setup.py +28 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from NMIXStudio.Container.NmiFrame import*
|
|
2
|
+
from NMIXStudio.Container.NmiImage import NMIImage
|
|
3
|
+
from NMIXStudio.Container.NmiImage import NMIImageBuilder
|
|
4
|
+
from NMIXStudio.Container.NmiContainer.enums import*
|
|
5
|
+
import json
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
class NMIContainer():
|
|
9
|
+
def __init__(self,containerName:str = None):
|
|
10
|
+
if(containerName is None):
|
|
11
|
+
containerName = "Default_" + datetime.now().strftime("%Y%m%d%H%M%S")
|
|
12
|
+
self.containerName = containerName
|
|
13
|
+
self.ImageList = []
|
|
14
|
+
self.WidthPixel:int = None
|
|
15
|
+
self.HeightPixel:int = None
|
|
16
|
+
self.RealHeight:float = None
|
|
17
|
+
self.RealWidth:float = None
|
|
18
|
+
self.RealHeightUnit:ScaleUnit = None
|
|
19
|
+
self.RealWidthUnit:ScaleUnit = None
|
|
20
|
+
self.RealHeightUnitPrefix:ScalePrefix = None
|
|
21
|
+
self.RealWidthUnitPrefix:ScalePrefix = None
|
|
22
|
+
|
|
23
|
+
def AddNewImage(self,frameType:FrameChannels,realBufferUnit:ScaleUnit = ScaleUnit.Meter,realBufferUnitPrefix:ScalePrefix = ScalePrefix.micro):
|
|
24
|
+
self.NMIImageBuilder = NMIImageBuilder()
|
|
25
|
+
newImage = (self.NMIImageBuilder
|
|
26
|
+
.SetChannel(frameType)
|
|
27
|
+
.SetWidthPixe(self.WidthPixel)
|
|
28
|
+
.SetHeightPixel(self.HeightPixel)
|
|
29
|
+
.SetRealHeight(self.RealHeight)
|
|
30
|
+
.SetRealWidth(self.RealWidth)
|
|
31
|
+
.SetRealHeightUnitPrefix(self.RealHeightUnitPrefix)
|
|
32
|
+
.SetRealWidthUnitPrefix(self.RealWidthUnitPrefix)
|
|
33
|
+
.SetRealHeightUnit(self.RealHeightUnit)
|
|
34
|
+
.SetRealWidthUnit(self.RealWidthUnit)
|
|
35
|
+
.SetRealBufferUnit(realBufferUnit)
|
|
36
|
+
.SetRealBufferUnitPrefix(realBufferUnitPrefix)
|
|
37
|
+
.Build())
|
|
38
|
+
self.ImageList.append(newImage)
|
|
39
|
+
|
|
40
|
+
def GetImageFromChannel(self,channel:FrameChannels)->NMIImage:
|
|
41
|
+
for image in self.ImageList:
|
|
42
|
+
image: NMIImage = image
|
|
43
|
+
if image.channel == channel:
|
|
44
|
+
return image
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
def GetFrameFromChannel(self,channel:FrameChannels)->NMIFrame:
|
|
48
|
+
for image in self.ImageList:
|
|
49
|
+
image: NMIImage = image
|
|
50
|
+
if image.channel == channel:
|
|
51
|
+
return image.GetFirstFrame()
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
def AddPixelToRawBuffer_FromAPIRequest(self,data):
|
|
55
|
+
for image in self.ImageList:
|
|
56
|
+
image: NMIImage = image
|
|
57
|
+
image.AddPixelToRawBuffer_FromAPIRequest(data)
|
|
58
|
+
|
|
59
|
+
def GetImageList(self):
|
|
60
|
+
return self.ImageList
|
|
61
|
+
|
|
62
|
+
def _GetJsonObject(self):
|
|
63
|
+
jsonObject = {
|
|
64
|
+
"ContainerName": self.containerName,
|
|
65
|
+
"WidthPixel": self.WidthPixel,
|
|
66
|
+
"HeightPixel": self.HeightPixel,
|
|
67
|
+
"RealHeight": self.RealHeight,
|
|
68
|
+
"RealWidth": self.RealWidth,
|
|
69
|
+
"RealHeightUnit": self.RealHeightUnit.name,
|
|
70
|
+
"RealWidthUnit": self.RealWidthUnit.name,
|
|
71
|
+
"RealHeightUnitPrefix": self.RealHeightUnitPrefix.name,
|
|
72
|
+
"RealWidthUnitPrefix": self.RealWidthUnitPrefix.name,
|
|
73
|
+
"ImageList": self._GetImageListJsonObject()
|
|
74
|
+
}
|
|
75
|
+
return jsonObject
|
|
76
|
+
|
|
77
|
+
def _GetImageListJsonObject(self):
|
|
78
|
+
_list = []
|
|
79
|
+
for image in self.ImageList:
|
|
80
|
+
image:NMIImage = image
|
|
81
|
+
_list.append(image._GetJsonObject())
|
|
82
|
+
return _list
|
|
83
|
+
|
|
84
|
+
def Save(self,filename:str):
|
|
85
|
+
data = self._GetJsonObject()
|
|
86
|
+
with open(filename, 'w') as file:
|
|
87
|
+
json.dump(data, file, indent=4)
|
|
88
|
+
|
|
89
|
+
def _LoadFromJsonObject(self,data:dict):
|
|
90
|
+
self.containerName = data["ContainerName"]
|
|
91
|
+
self.WidthPixel = data["WidthPixel"]
|
|
92
|
+
self.HeightPixel = data["HeightPixel"]
|
|
93
|
+
self.RealHeight = data["RealHeight"]
|
|
94
|
+
self.RealWidth = data["RealWidth"]
|
|
95
|
+
self.RealHeightUnit = ScaleUnit[data["RealHeightUnit"]]
|
|
96
|
+
self.RealWidthUnit = ScaleUnit[data["RealWidthUnit"]]
|
|
97
|
+
self.RealHeightUnitPrefix = ScalePrefix[data["RealHeightUnitPrefix"]]
|
|
98
|
+
self.RealWidthUnitPrefix = ScalePrefix[data["RealWidthUnitPrefix"]]
|
|
99
|
+
self.ImageList = []
|
|
100
|
+
for image in data["ImageList"]:
|
|
101
|
+
newImage = NMIImage()
|
|
102
|
+
newImage._LoadFromJsonObject(image)
|
|
103
|
+
self.ImageList.append(newImage)
|
|
104
|
+
|
|
105
|
+
def Load(self,filename:str):
|
|
106
|
+
with open(filename, 'r') as file:
|
|
107
|
+
data = json.load(file)
|
|
108
|
+
self._LoadFromJsonObject(data)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from NMIXStudio.Container.NmiFrame import*
|
|
2
|
+
from NMIXStudio.Container.NmiContainer import NMIContainer
|
|
3
|
+
from NMIXStudio.Container.NmiContainer.enums import*
|
|
4
|
+
|
|
5
|
+
class NMIContainerBuilder():
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.container = NMIContainer()
|
|
8
|
+
|
|
9
|
+
def SetWidthPixel(self,width):
|
|
10
|
+
self.container.WidthPixel = width
|
|
11
|
+
return self
|
|
12
|
+
def SetHeightPixel(self,height):
|
|
13
|
+
self.container.HeightPixel = height
|
|
14
|
+
return self
|
|
15
|
+
def SetRealHeight(self,height):
|
|
16
|
+
self.container.RealHeight = height
|
|
17
|
+
return self
|
|
18
|
+
def SetRealWidth(self,width):
|
|
19
|
+
self.container.RealWidth = width
|
|
20
|
+
return self
|
|
21
|
+
def SetRealHeightUnit(self,unit:ScaleUnit):
|
|
22
|
+
self.container.RealHeightUnit = unit
|
|
23
|
+
return self
|
|
24
|
+
def SetRealWidthUnit(self,unit:ScaleUnit):
|
|
25
|
+
self.container.RealWidthUnit = unit
|
|
26
|
+
return self
|
|
27
|
+
|
|
28
|
+
def SetRealHeightUnitPrefix(self,prefix:ScalePrefix):
|
|
29
|
+
self.container.RealHeightUnitPrefix = prefix
|
|
30
|
+
return self
|
|
31
|
+
def SetRealWidthUnitPrefix(self,prefix:ScalePrefix):
|
|
32
|
+
self.container.RealWidthUnitPrefix = prefix
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def AddImageChannel(self,channel:FrameChannels):
|
|
36
|
+
self.container.AddNewImage(channel)
|
|
37
|
+
return self
|
|
38
|
+
|
|
39
|
+
def Build(self):
|
|
40
|
+
return self.container
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class ScalePrefix(Enum):
|
|
4
|
+
giga = 0
|
|
5
|
+
mega = 1
|
|
6
|
+
kilo = 2
|
|
7
|
+
one = 3
|
|
8
|
+
milli = 4
|
|
9
|
+
micro = 5
|
|
10
|
+
nano = 6
|
|
11
|
+
angstrom = 7
|
|
12
|
+
pico = 8
|
|
13
|
+
femto = 9
|
|
14
|
+
|
|
15
|
+
class ScaleUnit(Enum):
|
|
16
|
+
Volt = 0
|
|
17
|
+
Amper = 1
|
|
18
|
+
Hertz = 2
|
|
19
|
+
Meter = 3
|
|
20
|
+
Gram = 4
|
|
21
|
+
Gauss = 5
|
|
22
|
+
Degrees = 6
|
|
23
|
+
Newton = 7
|
|
24
|
+
Farad = 8
|
|
25
|
+
Ohm = 9
|
|
26
|
+
VoltRms = 10
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from NMIXStudio.Container.NmiFrame.frameChannels import FrameChannels, GetAPIResponseKeyForChannel
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
class NMIFrame():
|
|
5
|
+
def __init__(self,width:int,height:int,channel:FrameChannels):
|
|
6
|
+
self.channel:FrameChannels=channel
|
|
7
|
+
self.width:int=width
|
|
8
|
+
self.height:int=height
|
|
9
|
+
self.rawBuffer = []
|
|
10
|
+
self.realBuffer = []
|
|
11
|
+
|
|
12
|
+
def Get8BitImageData(self)->np.array:
|
|
13
|
+
image_data = np.array(self.rawBuffer).reshape((self.height, self.width))
|
|
14
|
+
image_data = ((image_data - np.min(image_data)) / (np.max(image_data) - np.min(image_data)) * 255).astype(np.uint8)
|
|
15
|
+
return image_data
|
|
16
|
+
|
|
17
|
+
def Get16BitImageData(self) -> np.array:
|
|
18
|
+
image_data = np.array(self.rawBuffer).reshape((self.height, self.width))
|
|
19
|
+
# Veriyi normalize et ve 16-bit'e ölçekle
|
|
20
|
+
image_data = ((image_data - np.min(image_data)) / (np.max(image_data) - np.min(image_data)) * 65535).astype(np.uint16)
|
|
21
|
+
return image_data
|
|
22
|
+
|
|
23
|
+
def GetRawImageData(self) -> np.array:
|
|
24
|
+
image_data = np.array(self.rawBuffer).reshape((self.height, self.width))
|
|
25
|
+
return image_data
|
|
26
|
+
|
|
27
|
+
def UpdateFrameRawBuffer_FromAPIRequest(self,data:dict):
|
|
28
|
+
if "RawBuffer" not in data:
|
|
29
|
+
return None
|
|
30
|
+
data_string = data["RawBuffer"]
|
|
31
|
+
self.rawBuffer = np.array([int(x) for x in data_string.split(";")], dtype=np.int32)
|
|
32
|
+
|
|
33
|
+
def UpdateFrameRealBuffer_FromAPIRequest(self,data:dict):
|
|
34
|
+
if "RealBuffer" not in data:
|
|
35
|
+
return None
|
|
36
|
+
data_string = data["RealBuffer"]
|
|
37
|
+
data = np.array([int(x) for x in data_string.split(";")], dtype=np.int32)
|
|
38
|
+
self.realBuffer = data.reshape(self.height,self.width)
|
|
39
|
+
|
|
40
|
+
def AddPixelToRawBuffer_FromAPIRequest(self,data:dict):
|
|
41
|
+
key = GetAPIResponseKeyForChannel(self.channel)
|
|
42
|
+
if key is None:
|
|
43
|
+
return None
|
|
44
|
+
if key not in data:
|
|
45
|
+
return None
|
|
46
|
+
_bufferData = float(data[key])
|
|
47
|
+
self.rawBuffer.append(_bufferData)
|
|
48
|
+
|
|
49
|
+
def AddPixelToRawBuffer(self,data:float):
|
|
50
|
+
self.rawBuffer.append(data)
|
|
51
|
+
|
|
52
|
+
def AddPixelToRealBuffer(self,data):
|
|
53
|
+
self.realBuffer.append(data)
|
|
54
|
+
|
|
55
|
+
def _GetJsonObject(self):
|
|
56
|
+
jsonObject = {
|
|
57
|
+
"Width": self.width,
|
|
58
|
+
"Height": self.height,
|
|
59
|
+
"RawBuffer": self.rawBuffer,
|
|
60
|
+
"RealBuffer": self.realBuffer
|
|
61
|
+
}
|
|
62
|
+
return jsonObject
|
|
63
|
+
|
|
64
|
+
def _LoadFromJsonObject(self,data:dict):
|
|
65
|
+
self.width = data["Width"]
|
|
66
|
+
self.height = data["Height"]
|
|
67
|
+
self.rawBuffer = data["RawBuffer"]
|
|
68
|
+
self.realBuffer = data["RealBuffer"]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class FrameChannels(Enum):
|
|
4
|
+
Channel_Vz = 0,
|
|
5
|
+
Channel_Phase1 = 1,
|
|
6
|
+
Channel_Phase2 = 2,
|
|
7
|
+
Channel_Rms1 = 3,
|
|
8
|
+
Channel_Rms2 = 4,
|
|
9
|
+
Channel_WorkFunction = 5,
|
|
10
|
+
Channel_VHall = 6,
|
|
11
|
+
Channel_IHall = 7,
|
|
12
|
+
Channel_Spare3 = 8,
|
|
13
|
+
Channel_Spare4 = 9,
|
|
14
|
+
Channel_Vpd = 10,
|
|
15
|
+
Channel_VpdRef = 11,
|
|
16
|
+
Channel_VpdSig = 12,
|
|
17
|
+
Channel_Spare8 = 13,
|
|
18
|
+
Channel_Spare9 = 14,
|
|
19
|
+
Channel_Spare10 = 15,
|
|
20
|
+
Channel_FN10 = 16,
|
|
21
|
+
Channel_FN = 17,
|
|
22
|
+
Channel_FL = 18,
|
|
23
|
+
Channel_FT = 19,
|
|
24
|
+
Channel_DeltaF = 20,
|
|
25
|
+
Channel_ITunnel = 21,
|
|
26
|
+
|
|
27
|
+
Channel_Custom1 = 31,
|
|
28
|
+
Channel_Custom2 = 32,
|
|
29
|
+
Channel_Custom3 = 33,
|
|
30
|
+
Channel_Custom4 = 34,
|
|
31
|
+
Channel_Custom5 = 35,
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def GetAPIResponseKeyForChannel(channel:FrameChannels):
|
|
35
|
+
if channel == FrameChannels.Channel_Vz:
|
|
36
|
+
return "Vz"
|
|
37
|
+
if channel == FrameChannels.Channel_Phase1:
|
|
38
|
+
return "Lia1Phase"
|
|
39
|
+
if channel == FrameChannels.Channel_Phase2:
|
|
40
|
+
return "Lia2Phase"
|
|
41
|
+
if channel == FrameChannels.Channel_Rms1:
|
|
42
|
+
return "Lia1RMS"
|
|
43
|
+
if channel == FrameChannels.Channel_Rms2:
|
|
44
|
+
return "Lia2RMS"
|
|
45
|
+
if channel == FrameChannels.Channel_WorkFunction:
|
|
46
|
+
return "WorkFunction"
|
|
47
|
+
if channel == FrameChannels.Channel_VHall:
|
|
48
|
+
return "VHall"
|
|
49
|
+
if channel == FrameChannels.Channel_IHall:
|
|
50
|
+
return "IHall"
|
|
51
|
+
if channel == FrameChannels.Channel_ITunnel:
|
|
52
|
+
return "It"
|
|
53
|
+
if channel == FrameChannels.Channel_Spare3:
|
|
54
|
+
return "Spare3"
|
|
55
|
+
if channel == FrameChannels.Channel_Spare4:
|
|
56
|
+
return "Spare4"
|
|
57
|
+
if channel == FrameChannels.Channel_Vpd:
|
|
58
|
+
return "Vpd"
|
|
59
|
+
if channel == FrameChannels.Channel_VpdRef:
|
|
60
|
+
return "VpdRef"
|
|
61
|
+
if channel == FrameChannels.Channel_VpdSig:
|
|
62
|
+
return "VpdSig"
|
|
63
|
+
if channel == FrameChannels.Channel_Spare8:
|
|
64
|
+
return "Spare8"
|
|
65
|
+
if channel == FrameChannels.Channel_Spare9:
|
|
66
|
+
return "Spare9"
|
|
67
|
+
if channel == FrameChannels.Channel_Spare10:
|
|
68
|
+
return "Spare10"
|
|
69
|
+
if channel == FrameChannels.Channel_FN10:
|
|
70
|
+
return "Fnx10"
|
|
71
|
+
if channel == FrameChannels.Channel_FN:
|
|
72
|
+
return "Fn"
|
|
73
|
+
if channel == FrameChannels.Channel_FL:
|
|
74
|
+
return "Fl"
|
|
75
|
+
if channel == FrameChannels.Channel_FT:
|
|
76
|
+
return "Ft"
|
|
77
|
+
if channel == FrameChannels.Channel_DeltaF:
|
|
78
|
+
return "DeltaF"
|
|
79
|
+
return ""
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from NMIXStudio.Container.NmiFrame import*
|
|
2
|
+
from NMIXStudio.Container.NmiContainer.enums import*
|
|
3
|
+
|
|
4
|
+
class NMIImage():
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.imageName = None
|
|
7
|
+
self.WidthPixel:int = None
|
|
8
|
+
self.HeightPixel:int = None
|
|
9
|
+
self.RealHeight:float = None
|
|
10
|
+
self.RealWidth:float = None
|
|
11
|
+
self.RealHeightUnit:ScaleUnit = None
|
|
12
|
+
self.RealWidthUnit:ScaleUnit = None
|
|
13
|
+
self.RealHeightUnitPrefix:ScalePrefix = None
|
|
14
|
+
self.RealWidthUnitPrefix:ScalePrefix = None
|
|
15
|
+
self.RealBufferUnit:ScaleUnit = None
|
|
16
|
+
self.RealBufferUnitPrefix:ScalePrefix = None
|
|
17
|
+
self.channel:FrameChannels = None
|
|
18
|
+
self.frameList = []
|
|
19
|
+
|
|
20
|
+
def AddPixelToRawBuffer_FromAPIRequest(self,data:dict,index = 0):
|
|
21
|
+
frame:NMIFrame = self.frameList[index]
|
|
22
|
+
frame.AddPixelToRawBuffer_FromAPIRequest(data)
|
|
23
|
+
|
|
24
|
+
def UpdateFrameRawBuffer_FromAPIRequest(self,data:dict,index = 0):
|
|
25
|
+
frame:NMIFrame = self.frameList[index]
|
|
26
|
+
frame.UpdateFrameRawBuffer_FromAPIRequest(data)
|
|
27
|
+
|
|
28
|
+
def AddPixelToRealBuffer(self,data:dict,index = 0):
|
|
29
|
+
frame:NMIFrame = self.frameList[index]
|
|
30
|
+
frame.AddPixelToRealBuffer(data)
|
|
31
|
+
|
|
32
|
+
def AddPixelToRawBuffer(self,data,index = 0):
|
|
33
|
+
frame:NMIFrame = self.frameList[index]
|
|
34
|
+
frame.AddPixelToRawBuffer(data)
|
|
35
|
+
|
|
36
|
+
def CreateNewFrame(self):
|
|
37
|
+
newFrame = NMIFrame(self.WidthPixel,self.HeightPixel,self.channel)
|
|
38
|
+
self.frameList.append(newFrame)
|
|
39
|
+
|
|
40
|
+
def GetFrameList(self):
|
|
41
|
+
return self.frameList
|
|
42
|
+
|
|
43
|
+
def GetFirstFrame(self)->NMIFrame:
|
|
44
|
+
return self.frameList[0]
|
|
45
|
+
|
|
46
|
+
def _GetJsonObject(self):
|
|
47
|
+
jsonObject = {
|
|
48
|
+
"ImageName": self.imageName,
|
|
49
|
+
"WidthPixel": self.WidthPixel,
|
|
50
|
+
"HeightPixel": self.HeightPixel,
|
|
51
|
+
"RealHeight": self.RealHeight,
|
|
52
|
+
"RealWidth": self.RealWidth,
|
|
53
|
+
"RealHeightUnit": self.RealHeightUnit.name,
|
|
54
|
+
"RealWidthUnit": self.RealWidthUnit.name,
|
|
55
|
+
"RealHeightUnitPrefix": self.RealHeightUnitPrefix.name,
|
|
56
|
+
"RealWidthUnitPrefix": self.RealWidthUnitPrefix.name,
|
|
57
|
+
"RealBufferUnit": self.RealBufferUnit.name,
|
|
58
|
+
"RealBufferUnitPrefix": self.RealBufferUnitPrefix.name,
|
|
59
|
+
"Channel": self.channel.name,
|
|
60
|
+
"Frames": self._GetJsonObjectFrameList()
|
|
61
|
+
}
|
|
62
|
+
return jsonObject
|
|
63
|
+
|
|
64
|
+
def _GetJsonObjectFrameList(self):
|
|
65
|
+
_list = []
|
|
66
|
+
for frame in self.frameList:
|
|
67
|
+
frame:NMIFrame = frame
|
|
68
|
+
_list.append(frame._GetJsonObject())
|
|
69
|
+
return _list
|
|
70
|
+
|
|
71
|
+
def _LoadFromJsonObject(self,data:dict):
|
|
72
|
+
self.imageName = data["ImageName"]
|
|
73
|
+
self.WidthPixel = data["WidthPixel"]
|
|
74
|
+
self.HeightPixel = data["HeightPixel"]
|
|
75
|
+
self.RealHeight = data["RealHeight"]
|
|
76
|
+
self.RealWidth = data["RealWidth"]
|
|
77
|
+
self.RealHeightUnit = ScaleUnit[data["RealHeightUnit"]]
|
|
78
|
+
self.RealWidthUnit = ScaleUnit[data["RealWidthUnit"]]
|
|
79
|
+
self.RealHeightUnitPrefix = ScalePrefix[data["RealHeightUnitPrefix"]]
|
|
80
|
+
self.RealWidthUnitPrefix = ScalePrefix[data["RealWidthUnitPrefix"]]
|
|
81
|
+
self.RealBufferUnit = ScaleUnit[data["RealBufferUnit"]]
|
|
82
|
+
self.RealBufferUnitPrefix = ScalePrefix[data["RealBufferUnitPrefix"]]
|
|
83
|
+
self.channel = FrameChannels[data["Channel"]]
|
|
84
|
+
for frameData in data["Frames"]:
|
|
85
|
+
frame = NMIFrame(self.WidthPixel,self.HeightPixel,self.channel)
|
|
86
|
+
frame._LoadFromJsonObject(frameData)
|
|
87
|
+
self.frameList.append(frame)
|
|
88
|
+
|
|
89
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from NMIXStudio.Container.NmiImage.image import NMIImage
|
|
2
|
+
from NMIXStudio.Container.NmiContainer.enums import*
|
|
3
|
+
from NMIXStudio.Container.NmiFrame.frameChannels import*
|
|
4
|
+
class NMIImageBuilder():
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.Image = NMIImage()
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
def SetWidthPixe(self,width):
|
|
10
|
+
self.Image.WidthPixel = width
|
|
11
|
+
return self
|
|
12
|
+
|
|
13
|
+
def SetHeightPixel(self,height):
|
|
14
|
+
self.Image.HeightPixel = height
|
|
15
|
+
return self
|
|
16
|
+
|
|
17
|
+
def SetRealHeight(self,height):
|
|
18
|
+
self.Image.RealHeight = height
|
|
19
|
+
return self
|
|
20
|
+
|
|
21
|
+
def SetRealWidth(self,width):
|
|
22
|
+
self.Image.RealWidth = width
|
|
23
|
+
return self
|
|
24
|
+
|
|
25
|
+
def SetRealHeightUnit(self,unit:ScaleUnit):
|
|
26
|
+
self.Image.RealHeightUnit = unit
|
|
27
|
+
return self
|
|
28
|
+
|
|
29
|
+
def SetRealWidthUnit(self,unit:ScaleUnit):
|
|
30
|
+
self.Image.RealWidthUnit = unit
|
|
31
|
+
return self
|
|
32
|
+
|
|
33
|
+
def SetRealHeightUnitPrefix(self,prefix:ScalePrefix):
|
|
34
|
+
self.Image.RealHeightUnitPrefix = prefix
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def SetRealWidthUnitPrefix(self,prefix:ScalePrefix):
|
|
38
|
+
self.Image.RealWidthUnitPrefix = prefix
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def SetRealBufferUnit(self,unit:ScaleUnit):
|
|
42
|
+
self.Image.RealBufferUnit = unit
|
|
43
|
+
return self
|
|
44
|
+
def SetRealBufferUnitPrefix(self,prefix:ScalePrefix):
|
|
45
|
+
self.Image.RealBufferUnitPrefix = prefix
|
|
46
|
+
return self
|
|
47
|
+
|
|
48
|
+
def SetChannel(self,channel:FrameChannels):
|
|
49
|
+
self.Image.channel = channel
|
|
50
|
+
self.Image.imageName = channel.name
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def Build(self)->NMIImage:
|
|
54
|
+
self.Image.CreateNewFrame()
|
|
55
|
+
return self.Image
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from .utils import ExternalScanDevice
|
|
2
|
+
from pylablib.devices import Andor
|
|
3
|
+
import numpy as np
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ReadMode(Enum):
|
|
8
|
+
FVB = "fvb"
|
|
9
|
+
IMAGE = "image"
|
|
10
|
+
|
|
11
|
+
class TriggerMode(Enum):
|
|
12
|
+
INTERNAL = "int"
|
|
13
|
+
EXTERNAL = "ext"
|
|
14
|
+
|
|
15
|
+
class AcquisitionMode(Enum):
|
|
16
|
+
SINGLE = "single"
|
|
17
|
+
ACCUM = "accum"
|
|
18
|
+
|
|
19
|
+
class AndorCamera(ExternalScanDevice):
|
|
20
|
+
def __init__(self):
|
|
21
|
+
self.camera = None
|
|
22
|
+
|
|
23
|
+
def connect(self):
|
|
24
|
+
"""Connect to the Andor camera."""
|
|
25
|
+
camera_count = Andor.get_cameras_number_SDK2()
|
|
26
|
+
if camera_count == 0:
|
|
27
|
+
raise Exception("No cameras found.")
|
|
28
|
+
self.camera = Andor.AndorSDK2Camera()
|
|
29
|
+
print("Camera connected.")
|
|
30
|
+
|
|
31
|
+
def disconnect(self):
|
|
32
|
+
"""Disconnect the camera."""
|
|
33
|
+
if self.camera and self.camera.is_opened():
|
|
34
|
+
self.camera.close()
|
|
35
|
+
print("Camera disconnected.")
|
|
36
|
+
|
|
37
|
+
def set_temperature(self, temperature):
|
|
38
|
+
"""Set the camera temperature."""
|
|
39
|
+
if self.camera:
|
|
40
|
+
self.camera.set_temperature(temperature)
|
|
41
|
+
self.camera.set_cooler()
|
|
42
|
+
print(f"Temperature set to {temperature}C.")
|
|
43
|
+
|
|
44
|
+
def get_status(self):
|
|
45
|
+
"""Get the current status of the camera."""
|
|
46
|
+
if self.camera:
|
|
47
|
+
return self.camera.get_full_status()
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def get_info(self):
|
|
51
|
+
"""Get full camera information."""
|
|
52
|
+
if self.camera:
|
|
53
|
+
return self.camera.get_full_info()
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
def set_exposure(self, exposure_time):
|
|
57
|
+
"""Set the exposure time."""
|
|
58
|
+
if self.camera:
|
|
59
|
+
self.camera.set_exposure(exposure_time)
|
|
60
|
+
print(f"Exposure time set to {exposure_time} seconds.")
|
|
61
|
+
|
|
62
|
+
def configure_acquisition(self, mode=AcquisitionMode.SINGLE, read_mode=ReadMode.FVB, trigger_mode=TriggerMode.INTERNAL, amp_settings=None):
|
|
63
|
+
"""Configure acquisition settings."""
|
|
64
|
+
if self.camera:
|
|
65
|
+
self.camera.set_read_mode(read_mode.value)
|
|
66
|
+
self.camera.set_trigger_mode(trigger_mode.value)
|
|
67
|
+
self.camera.setup_shutter("auto")
|
|
68
|
+
|
|
69
|
+
if amp_settings:
|
|
70
|
+
self.camera.set_amp_mode(
|
|
71
|
+
channel=amp_settings.get("channel", 0),
|
|
72
|
+
oamp=amp_settings.get("oamp", 1),
|
|
73
|
+
hsspeed=amp_settings.get("hsspeed", 2),
|
|
74
|
+
preamp=amp_settings.get("preamp", 2),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
self.camera.setup_acquisition(mode.value)
|
|
78
|
+
print(f"Acquisition configured. Mode: {mode.name}, Read Mode: {read_mode.name}, Trigger Mode: {trigger_mode.name}.")
|
|
79
|
+
|
|
80
|
+
def acquire_spectrum(self):
|
|
81
|
+
"""Acquire a Raman spectrum."""
|
|
82
|
+
if self.camera:
|
|
83
|
+
spectrum = self.camera.snap()
|
|
84
|
+
return spectrum[0] # Return the spectral data
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
def start_acquisition(self):
|
|
88
|
+
"""Start acquisition."""
|
|
89
|
+
if self.camera:
|
|
90
|
+
self.camera.start_acquisition()
|
|
91
|
+
print("Acquisition started.")
|
|
92
|
+
|
|
93
|
+
def stop_acquisition(self):
|
|
94
|
+
"""Stop acquisition."""
|
|
95
|
+
if self.camera:
|
|
96
|
+
self.camera.stop_acquisition()
|
|
97
|
+
print("Acquisition stopped.")
|
|
98
|
+
|
|
99
|
+
def clear_acquisition(self):
|
|
100
|
+
"""Clear acquisition settings."""
|
|
101
|
+
if self.camera:
|
|
102
|
+
self.camera.clear_acquisition()
|
|
103
|
+
print("Acquisition cleared.")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def GetScanData(self) -> float:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
|