barsukov 0.0.5__py3-none-any.whl → 1.0.8__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.

Potentially problematic release.


This version of barsukov might be problematic. Click here for more details.

barsukov/__init__.py CHANGED
@@ -1,14 +1,15 @@
1
- # Modules:
2
- from . import time
3
- from . import data
4
-
5
- # Objects/Functions:
6
- from .script import Script
7
- from .logger import Logger
8
-
9
- # Equipment Objects:
10
- from .exp.mwHP import mwHP
11
-
12
- __all__ = ["time", "formula", "data", "Script", "Logger", "mwHP"]
13
-
14
-
1
+ # Modules:
2
+ from . import time
3
+ from . import data
4
+
5
+ # Objects/Functions:
6
+ from .script import Script
7
+ from .logger import Logger
8
+ from .testpickle import *
9
+
10
+ # Equipment Objects:
11
+ from .exp.mwHP import mwHP
12
+
13
+ __all__ = ["time", "formula", "data", "Script", "Logger", "mwHP"]
14
+
15
+
barsukov/data/__init__.py CHANGED
@@ -0,0 +1 @@
1
+ from .fft import *
barsukov/data/fft.py CHANGED
@@ -1,87 +1,87 @@
1
- ### BEGIN Dependencies ###
2
- import numpy as np
3
- import scipy as sp
4
- from barsukov.logger import debug # Un-comment before implementing in pip
5
- ### END Dependencies ###
6
-
7
-
8
- def fft(x, y, equidistant_check=True, equidistant_rel_error=1e-4, remove_negative_f=False, inverse=False):
9
- ### Takes: x=list of real floats, y=list of data or list of lists of data. Data can be real or complex.
10
- ### Returns: freqs, fft_y_norm, msg
11
- ### This fft used to give wrong sign of the imaginary component because of the "wrong" definition of fft in np and sp
12
- ### Now it has been corrected to the Mathematica definition of fft = int ... exp(2pi f t)
13
- msg = ''
14
- if equidistant_check:
15
- diffs = np.diff(x)
16
- if not np.allclose(diffs, diffs[0], rtol=equidistant_rel_error):
17
- # x is not equidistant, must start interpolating
18
- x,y = make_equidistant(x, y, step=None)
19
- y = y.T
20
- msg += debug('fft(x,y) made x,y equidistant.')
21
-
22
- y = np.array(y)
23
- #print(y)
24
-
25
- if y.ndim == 1:
26
- # y is 1D, treat it as a single column
27
- n = len(y) # Number of points in the column
28
- if inverse is False: fft_y = np.fft.ifft(y) * n # np fft has the "wrong" imag sign
29
- else: fft_y = np.fft.fft(y) # That's why fft and ifft are inverted in this code
30
- else:
31
- # y is 2D, treat it as multiple columns
32
- n = y.shape[1] # Number of points in each column
33
- if inverse is False: fft_y = np.fft.ifft(y, axis=1) * n # np fft has the "wrong" imag sign
34
- else: fft_y = np.fft.fft(y, axis=1) # That's why fft and ifft are inverted in this code
35
-
36
- sample_spacing = ( x[-1] - x[0] ) / (n-1)
37
- #print(n, sample_spacing, x[1] - x[0])
38
- fft_y_norm = fft_y * sample_spacing # This normalizes FFT to mathematically correct
39
- freqs = np.fft.fftfreq(n, d=sample_spacing)
40
-
41
- if remove_negative_f is False:
42
- sorted_indices = np.argsort(freqs)
43
- freqs = freqs[sorted_indices]
44
- if isinstance(fft_y_norm[0], (list, np.ndarray)): # If fft_y_norm contains multiple columns
45
- fft_y_norm = [x[sorted_indices] for x in fft_y_norm]
46
- else: # If fft_y_norm is a single column
47
- fft_y_norm = fft_y_norm[sorted_indices]
48
- msg += debug('fft(x,y) sorted negative and positive frequencies.')
49
- else:
50
- mask = freqs >= 0 # Boolean array with Falses for negative frequencies, effectively removing them
51
- freqs = freqs[mask]
52
- # If fft_y_norm contains multiple columns:
53
- if isinstance(fft_y_norm[0], (list, np.ndarray)):
54
- fft_y_norm = [x[mask] for x in fft_y_norm]
55
- else: # If fft_y_norm is a single column
56
- fft_y_norm = fft_y_norm[mask]
57
- msg += debug('fft(x,y) removed negative frequencies.')
58
-
59
- msg += debug('freqs, fft_y_norm, msg = fft(x,y) is done.\nThe forward fft approximates the mathematically correct integral over ...exp(+i2pift).\nNow do not forget to apply np.abs(fft_y_norm), np.angle(fft_y_norm), fft_y_norm.real, fft_y_norm.imag')
60
- return freqs, fft_y_norm, msg
61
-
62
- def ifft(x, y, equidistant_check=True, equidistant_rel_error=1e-4, remove_negative_f=False):
63
- return fft(x, y, equidistant_check=equidistant_check, equidistant_rel_error=equidistant_rel_error, remove_negative_f=remove_negative_f, inverse=True)
64
-
65
- def make_equidistant(x, y, step=None):
66
- ### Takes one column x and one or more columns y and makes them equidistant in x
67
- ### Returns new_x, new_y. The number of points will likely change.
68
- if step is None:
69
- # Calculate the smallest difference between consecutive elements
70
- min_step = np.min(np.diff(x))
71
- else:
72
- min_step = step
73
-
74
- # Generate the new equidistant x array
75
- new_x = np.arange(x[0], x[-1] + min_step, min_step)
76
-
77
- if isinstance(y[0], (list, np.ndarray)): # If y contains multiple columns
78
- new_y = []
79
- for y_column in y:
80
- interpolation_function = sp.interpolate.interp1d(x, y_column, kind='linear', fill_value='extrapolate')
81
- new_y.append(interpolation_function(new_x))
82
- new_y = np.array(new_y).T # Transpose to match the original structure
83
- else: # If y is a single column
84
- interpolation_function = sp.interpolate.interp1d(x, y, kind='linear', fill_value='extrapolate')
85
- new_y = interpolation_function(new_x)
86
-
87
- return new_x, new_y
1
+ ### BEGIN Dependencies ###
2
+ import numpy as np
3
+ import scipy as sp
4
+ from barsukov.logger import debug # Un-comment before implementing in pip
5
+ ### END Dependencies ###
6
+
7
+
8
+ def fft(x, y, equidistant_check=True, equidistant_rel_error=1e-4, remove_negative_f=False, inverse=False):
9
+ ### Takes: x=list of real floats, y=list of data or list of lists of data. Data can be real or complex.
10
+ ### Returns: freqs, fft_y_norm, msg
11
+ ### This fft used to give wrong sign of the imaginary component because of the "wrong" definition of fft in np and sp
12
+ ### Now it has been corrected to the Mathematica definition of fft = int ... exp(2pi f t)
13
+ msg = ''
14
+ if equidistant_check:
15
+ diffs = np.diff(x)
16
+ if not np.allclose(diffs, diffs[0], rtol=equidistant_rel_error):
17
+ # x is not equidistant, must start interpolating
18
+ x,y = make_equidistant(x, y, step=None)
19
+ y = y.T
20
+ msg += debug('fft(x,y) made x,y equidistant.')
21
+
22
+ y = np.array(y)
23
+ #print(y)
24
+
25
+ if y.ndim == 1:
26
+ # y is 1D, treat it as a single column
27
+ n = len(y) # Number of points in the column
28
+ if inverse is False: fft_y = np.fft.ifft(y) * n # np fft has the "wrong" imag sign
29
+ else: fft_y = np.fft.fft(y) # That's why fft and ifft are inverted in this code
30
+ else:
31
+ # y is 2D, treat it as multiple columns
32
+ n = y.shape[1] # Number of points in each column
33
+ if inverse is False: fft_y = np.fft.ifft(y, axis=1) * n # np fft has the "wrong" imag sign
34
+ else: fft_y = np.fft.fft(y, axis=1) # That's why fft and ifft are inverted in this code
35
+
36
+ sample_spacing = ( x[-1] - x[0] ) / (n-1)
37
+ #print(n, sample_spacing, x[1] - x[0])
38
+ fft_y_norm = fft_y * sample_spacing # This normalizes FFT to mathematically correct
39
+ freqs = np.fft.fftfreq(n, d=sample_spacing)
40
+
41
+ if remove_negative_f is False:
42
+ sorted_indices = np.argsort(freqs)
43
+ freqs = freqs[sorted_indices]
44
+ if isinstance(fft_y_norm[0], (list, np.ndarray)): # If fft_y_norm contains multiple columns
45
+ fft_y_norm = [x[sorted_indices] for x in fft_y_norm]
46
+ else: # If fft_y_norm is a single column
47
+ fft_y_norm = fft_y_norm[sorted_indices]
48
+ msg += debug('fft(x,y) sorted negative and positive frequencies.')
49
+ else:
50
+ mask = freqs >= 0 # Boolean array with Falses for negative frequencies, effectively removing them
51
+ freqs = freqs[mask]
52
+ # If fft_y_norm contains multiple columns:
53
+ if isinstance(fft_y_norm[0], (list, np.ndarray)):
54
+ fft_y_norm = [x[mask] for x in fft_y_norm]
55
+ else: # If fft_y_norm is a single column
56
+ fft_y_norm = fft_y_norm[mask]
57
+ msg += debug('fft(x,y) removed negative frequencies.')
58
+
59
+ msg += debug('freqs, fft_y_norm, msg = fft(x,y) is done.\nThe forward fft approximates the mathematically correct integral over ...exp(+i2pift).\nNow do not forget to apply np.abs(fft_y_norm), np.angle(fft_y_norm), fft_y_norm.real, fft_y_norm.imag')
60
+ return freqs, fft_y_norm, msg
61
+
62
+ def ifft(x, y, equidistant_check=True, equidistant_rel_error=1e-4, remove_negative_f=False):
63
+ return fft(x, y, equidistant_check=equidistant_check, equidistant_rel_error=equidistant_rel_error, remove_negative_f=remove_negative_f, inverse=True)
64
+
65
+ def make_equidistant(x, y, step=None):
66
+ ### Takes one column x and one or more columns y and makes them equidistant in x
67
+ ### Returns new_x, new_y. The number of points will likely change.
68
+ if step is None:
69
+ # Calculate the smallest difference between consecutive elements
70
+ min_step = np.min(np.diff(x))
71
+ else:
72
+ min_step = step
73
+
74
+ # Generate the new equidistant x array
75
+ new_x = np.arange(x[0], x[-1] + min_step, min_step)
76
+
77
+ if isinstance(y[0], (list, np.ndarray)): # If y contains multiple columns
78
+ new_y = []
79
+ for y_column in y:
80
+ interpolation_function = sp.interpolate.interp1d(x, y_column, kind='linear', fill_value='extrapolate')
81
+ new_y.append(interpolation_function(new_x))
82
+ new_y = np.array(new_y).T # Transpose to match the original structure
83
+ else: # If y is a single column
84
+ interpolation_function = sp.interpolate.interp1d(x, y, kind='linear', fill_value='extrapolate')
85
+ new_y = interpolation_function(new_x)
86
+
87
+ return new_x, new_y
barsukov/exp/exp_utils.py CHANGED
@@ -1,119 +1,136 @@
1
- ### BEGIN Dependencies ###
2
- import numpy as np
3
- import sys
4
- from barsukov.time import *
5
- ### END Dependencies
6
-
7
-
8
-
9
-
10
-
11
-
12
- ### BEGIN Helper functions
13
-
14
- def log_in_eq(eq_obj, msg, log='default'): # FINISHED 2024/10/26
15
- decorated_msg = str(eq_obj.msg_deco) + ' ' + msg
16
- if eq_obj.logger is None:
17
- if log=='no': return
18
- else: print(time_stamp() + ' ' + decorated_msg)
19
- else:
20
- eq_obj.logger.log(decorated_msg, log)
21
-
22
- def initialize_gpib(eq_obj):
23
- # Initializes a visa.open_resource(). Returns rm.open_resource(). Exits if error.
24
- if eq_obj.rm is None: # eq_obj has no ResourceManager
25
- if eq_obj.script is None: # If there is no Script
26
- eq_obj.log('Visa ResourceManager and Script have not been passed to me. I will attempt to initialize visa myself.', log='important')
27
- try:
28
- import pyvisa as visa
29
- eq_obj.rm = visa.ResourceManager()
30
- eq_obj.log('I just set my self.rm = visa.ResourceManager.', log='screen')
31
- except:
32
- eq_obj.log('I failed to initialize set my self.rm = visa.ResourceManager. I am sys-exiting.', log='important')
33
- sys.exit()
34
- else: # If there is a Script
35
- if eq_obj.script.rm is None: # If Script has no ResourceManager
36
- eq_obj.log('I see Script but it does not have rm. I am asking Script to initialize visa.ResourceManager and pass it to me.', log='important')
37
- try:
38
- eq_obj.rm = eq_obj.script.init_rm() # Script will try to init ResourceManager
39
- #print('eq_obj.rm initialized as ', eq_obj.rm)
40
- except:
41
- eq_obj.log('Error while Script was initializing visa.ResourceManager. I am sys-exiting.', log='important')
42
- sys.exit()
43
- else:
44
- eq_obj.log('Script has visa.ResourceManager. I am grabbing it.', log='screen')
45
- eq_obj.rm = eq_obj.script.rm
46
- if eq_obj.rm is None: # Just to double check if rm is in fact there.
47
- eq_obj.log('My last check showed that my self.rm is still None. I am sys-exiting.', log='important')
48
- sys.exit()
49
- # Now, we assume there is a resource manager
50
- if (eq_obj.gpib is None) or (eq_obj.gpib_card is None):
51
- eq_obj.log('GPIB card number or GPIB address is not set.', log='important')
52
- sys.exit()
53
- try:
54
- #print(eq_obj.rm)
55
- eq_obj.log('I am trying to rm.open_resource().', log='screen')
56
- y = eq_obj.rm.open_resource(f'GPIB{eq_obj.gpib_card}::{eq_obj.gpib}')
57
- #print('y=',y)
58
- return y
59
- except:
60
- eq_obj.log(f'I could not initialize rm.open_resource() for GPIB {eq_obj.gpib_card}::{eq_obj.gpib}. Also check visa_rm, just in case.', log='important')
61
- sys.exit()
62
-
63
- ### END Helper functions
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
- ### BEGIN Functions that are likely unnecessary
88
-
89
- def query_float(eq_obj, cmd):
90
- ### Returns float or np.nan
91
- try:
92
- q = eq_obj.eq.query(cmd)
93
- q = float(q) # Will it work with all equipment?
94
- return q
95
- except:
96
- eq_obj.log(f'Error while quering: \"{cmd}\".', log='important')
97
- return np.nan
98
-
99
- def write_float(eq_obj, cmd, value, digits, limits):
100
- value_differs = ''
101
- try:
102
- value = float(value)
103
- value_round = round(value, digits)
104
- if value_round < limits[0]:
105
- value_round = limits[0]
106
- if value_round > limits[1]:
107
- value_round = limits[1]
108
- if value_round != value:
109
- value_differs = f' But requested {value}.'
110
- cmd = ''.join( [value_round if el is None else el for el in cmd] )
111
- eq_obj.eq.write(cmd)
112
- write_error = False
113
- return write_error, value_differs
114
- except:
115
- write_error = True
116
- eq_obj.log(f'Error while writing: \"{cmd}\".', log='important')
117
- return write_error, value_differs
118
-
119
- ### END Functions that are likely unnecessary
1
+ ### BEGIN Dependencies ###
2
+ import numpy as np
3
+ import sys
4
+ from barsukov.time import *
5
+ ### END Dependencies
6
+
7
+
8
+
9
+
10
+
11
+
12
+ ### BEGIN Helper functions
13
+
14
+ def log_in_eq(eq_obj, msg, log='default'): # FINISHED 2024/10/26
15
+ decorated_msg = str(eq_obj.msg_deco) + ' ' + msg
16
+ if eq_obj.logger is None:
17
+ if log=='no': return
18
+ else: print(time_stamp() + ' ' + decorated_msg)
19
+ else:
20
+ eq_obj.logger.log(decorated_msg, log)
21
+
22
+ def initialize_gpib(eq_obj):
23
+ # Initializes a visa.open_resource(). Returns rm.open_resource(). Exits if error.
24
+ if eq_obj.rm is None: # eq_obj has no ResourceManager
25
+ if eq_obj.script is None: # If there is no Script
26
+ eq_obj.log('Visa ResourceManager and Script have not been passed to me. I will attempt to initialize visa myself.', log='important')
27
+ try:
28
+ import pyvisa as visa
29
+ eq_obj.rm = visa.ResourceManager()
30
+ eq_obj.log('I just set my self.rm = visa.ResourceManager.', log='screen')
31
+ except:
32
+ eq_obj.log('I failed to initialize set my self.rm = visa.ResourceManager. I am sys-exiting.', log='important')
33
+ sys.exit()
34
+ else: # If there is a Script
35
+ if eq_obj.script.rm is None: # If Script has no ResourceManager
36
+ eq_obj.log('I see Script but it does not have rm. I am asking Script to initialize visa.ResourceManager and pass it to me.', log='important')
37
+ try:
38
+ eq_obj.rm = eq_obj.script.init_rm() # Script will try to init ResourceManager
39
+ #print('eq_obj.rm initialized as ', eq_obj.rm)
40
+ except:
41
+ eq_obj.log('Error while Script was initializing visa.ResourceManager. I am sys-exiting.', log='important')
42
+ sys.exit()
43
+ else:
44
+ eq_obj.log('Script has visa.ResourceManager. I am grabbing it.', log='screen')
45
+ eq_obj.rm = eq_obj.script.rm
46
+ if eq_obj.rm is None: # Just to double check if rm is in fact there.
47
+ eq_obj.log('My last check showed that my self.rm is still None. I am sys-exiting.', log='important')
48
+ sys.exit()
49
+ # Now, we assume there is a resource manager
50
+ if (eq_obj.gpib is None) or (eq_obj.gpib_card is None):
51
+ eq_obj.log('GPIB card number or GPIB address is not set.', log='important')
52
+ sys.exit()
53
+ try:
54
+ #print(eq_obj.rm)
55
+ eq_obj.log('I am trying to rm.open_resource().', log='screen')
56
+ y = eq_obj.rm.open_resource(f'GPIB{eq_obj.gpib_card}::{eq_obj.gpib}')
57
+ #print('y=',y)
58
+ return y
59
+ except:
60
+ eq_obj.log(f'I could not initialize rm.open_resource() for GPIB {eq_obj.gpib_card}::{eq_obj.gpib}. Also check visa_rm, just in case.', log='important')
61
+ sys.exit()
62
+
63
+ def eq_disconnect(eq_obj):
64
+ try:
65
+ eq_obj.rm.close()
66
+ eq_obj.rm.visalib._registry.clear()
67
+ eq_obj.log( f'Successfully disconnected GPIB resource for {eq_obj.gpib_card}::{eq_obj.gpib}.', log='screen')
68
+ except:
69
+ eq_obj.log( f'Failed to disconnect GPIB resource for {eq_obj.gpib_card}::{eq_obj.gpib}.', log='screen')
70
+
71
+ def eq_reconnect(eq_obj):
72
+ try:
73
+ import pyvisa as visa
74
+ eq_obj.rm = visa.ResourceManager()
75
+ eq_obj.eq = initialize_gpib(eq_obj)
76
+ eq_obj.log( f'Successfully reconnected GPIB resource for {eq_obj.gpib_card}::{eq_obj.gpib}.', log='screen')
77
+ eq_obj.log( f'Initialized: {eq_obj.identify()}', log='important' )
78
+ except:
79
+ eq_obj.log(f'Failed to reconnect GPIB resource for {eq_obj.gpib_card}::{eq_obj.gpib}.', log='important')
80
+ ### END Helper functions
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+ ### BEGIN Functions that are likely unnecessary
105
+
106
+ def query_float(eq_obj, cmd):
107
+ ### Returns float or np.nan
108
+ try:
109
+ q = eq_obj.eq.query(cmd)
110
+ q = float(q) # Will it work with all equipment?
111
+ return q
112
+ except:
113
+ eq_obj.log(f'Error while quering: \"{cmd}\".', log='important')
114
+ return np.nan
115
+
116
+ def write_float(eq_obj, cmd, value, digits, limits):
117
+ value_differs = ''
118
+ try:
119
+ value = float(value)
120
+ value_round = round(value, digits)
121
+ if value_round < limits[0]:
122
+ value_round = limits[0]
123
+ if value_round > limits[1]:
124
+ value_round = limits[1]
125
+ if value_round != value:
126
+ value_differs = f' But requested {value}.'
127
+ cmd = ''.join( [value_round if el is None else el for el in cmd] )
128
+ eq_obj.eq.write(cmd)
129
+ write_error = False
130
+ return write_error, value_differs
131
+ except:
132
+ write_error = True
133
+ eq_obj.log(f'Error while writing: \"{cmd}\".', log='important')
134
+ return write_error, value_differs
135
+
136
+ ### END Functions that are likely unnecessary