pymodaq_utils 0.0.2__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.
@@ -0,0 +1,584 @@
1
+ import numbers
2
+ from typing import Union
3
+
4
+ import numpy
5
+ import numpy as np
6
+ from numbers import Number
7
+ from typing import List, Union, Tuple
8
+ from pymodaq_utils.logger import get_module_name, set_logger
9
+ from collections.abc import Iterable
10
+
11
+ logger = set_logger(get_module_name(__file__))
12
+
13
+
14
+ def my_moment(x, y):
15
+ """Returns the moments of a distribution y over an axe x
16
+
17
+ Parameters
18
+ ----------
19
+ x: list or ndarray
20
+ vector of floats
21
+ y: list or ndarray
22
+ vector of floats corresponding to the x axis
23
+
24
+ Returns
25
+ -------
26
+ m: list
27
+ Contains moment of order 0 (mean) and of order 1 (std) of the distribution y
28
+ """
29
+ dx = np.mean(np.diff(x))
30
+ norm = np.sum(y) * dx
31
+ m = [np.sum(x * y) * dx / norm]
32
+ m.extend([np.sqrt(np.sum((x - m[0]) ** 2 * y) * dx / norm)])
33
+ return m
34
+
35
+
36
+ def normalize(x):
37
+ x = x - np.min(x)
38
+ x = x / np.max(x)
39
+ return x
40
+
41
+
42
+ def normalize_to(array: np.ndarray, value: numbers.Number):
43
+ return normalize(array) * value
44
+
45
+
46
+ def odd_even(x: Union[int, np.ndarray]):
47
+ """
48
+ odd_even tells if a number (or an array) is odd (return True) or even (return False)
49
+
50
+ Parameters
51
+ ----------
52
+ x: the integer number (or array) to test
53
+
54
+ Returns
55
+ -------
56
+ bool : boolean or array of boolean
57
+ """
58
+ if not (isinstance(x, int) or (isinstance(x, np.ndarray) and x.dtype == int)):
59
+ raise TypeError(f'{x} should be an integer or an array of integers')
60
+ if isinstance(x, int):
61
+ if x % 2 == 0:
62
+ isodd = False
63
+ else:
64
+ isodd = True
65
+ else:
66
+ isodd = x % 2 != 0
67
+ return isodd
68
+
69
+
70
+ def greater2n(x):
71
+ """
72
+ return the first power of 2 greater than x
73
+ Parameters
74
+ ----------
75
+ x: (int or float) a number
76
+
77
+ Returns
78
+ -------
79
+ int: the power of 2 greater than x
80
+ """
81
+ if isinstance(x, bool):
82
+ raise TypeError(f'{x} should be an integer or a float')
83
+ if hasattr(x, '__iter__'):
84
+ res = []
85
+ for el in x:
86
+ if isinstance(el, bool):
87
+ raise TypeError(f'{el} should be an integer or a float')
88
+ if not (isinstance(el, int) or isinstance(el, float)):
89
+ raise TypeError(f'{x} elements should be integer or float')
90
+ res.append(1 << (int(el) - 1).bit_length())
91
+ if isinstance(x, np.ndarray):
92
+ return np.array(res)
93
+ else:
94
+ return res
95
+ else:
96
+ if not (isinstance(x, int) or isinstance(x, float)):
97
+ raise TypeError(f'{x} should be an integer or a float')
98
+ return 1 << (int(x) - 1).bit_length()
99
+
100
+
101
+ def linspace_step(start, stop, step):
102
+ """
103
+ Compute a regular linspace_step distribution from start to stop values.
104
+
105
+ =============== =========== ======================================
106
+ **Parameters** **Type** **Description**
107
+ *start* scalar the starting value of distribution
108
+ *stop* scalar the stopping value of distribution
109
+ *step* scalar the length of a distribution step
110
+ =============== =========== ======================================
111
+
112
+ Returns
113
+ -------
114
+
115
+ scalar array
116
+ The computed distribution axis as an array.
117
+ """
118
+ if np.sign(stop - start) != np.sign(step) or start == stop:
119
+ raise ValueError('Invalid value for one parameter')
120
+ Nsteps = int(np.ceil((stop - start) / step))
121
+ new_stop = start + (Nsteps - 1) * step
122
+ if np.abs(new_stop + step - stop) < 1e-12:
123
+ Nsteps += 1
124
+ new_stop = start + (Nsteps - 1) * step
125
+ return np.linspace(start, new_stop, Nsteps)
126
+
127
+
128
+ def linspace_step_N(start, step, Npts):
129
+ stop = (Npts - 1) * step + start
130
+ return linspace_step(start, stop, step)
131
+
132
+
133
+ def find_index(x, threshold: Union[Number, List[Number]]) -> List[tuple]:
134
+ """find_index finds the index ix such that x(ix) is the closest from threshold
135
+
136
+ Parameters
137
+ ----------
138
+ x : vector
139
+ threshold : list of real numbers
140
+
141
+ Returns
142
+ -------
143
+ out : list of 2-tuple containing ix,x[ix]
144
+ out=[(ix0,xval0),(ix1,xval1),...]
145
+ """
146
+
147
+ if not hasattr(threshold, '__iter__'):
148
+ threshold = [threshold]
149
+ out = []
150
+ for value in threshold:
151
+ ix = int(np.argmin(np.abs(x - value)))
152
+ out.append((ix, x[ix]))
153
+ return out
154
+
155
+
156
+ def find_common_index(x: Iterable, y: Iterable, x0: Number, y0: Number) -> Tuple:
157
+ """find the index in two vectors corresponding to x0 and y0"""
158
+ vals = x + 1j * y
159
+ val = x0 + 1j * y0
160
+ ind = int(np.argmin(np.abs(vals - val)))
161
+ return ind, x[ind], y[ind]
162
+
163
+
164
+ def gauss1D(x, x0, dx, n=1):
165
+ """
166
+ compute the gaussian function along a vector x, centered in x0 and with a
167
+ FWHM i intensity of dx. n=1 is for the standart gaussian while n>1 defines
168
+ a hypergaussian
169
+
170
+ Parameters
171
+ ----------
172
+ x: (ndarray) first axis of the 2D gaussian
173
+ x0: (float) the central position of the gaussian
174
+ dx: (float) :the FWHM of the gaussian
175
+ n=1 : an integer to define hypergaussian, n=1 by default for regular gaussian
176
+ Returns
177
+ -------
178
+ out : vector
179
+ the value taken by the gaussian along x axis
180
+
181
+ """
182
+ if dx <= 0:
183
+ raise ValueError('dx should be strictly positive')
184
+ if not isinstance(n, int):
185
+ raise TypeError('n should be a positive integer')
186
+ elif n < 0:
187
+ raise ValueError('n should be a positive integer')
188
+ out = np.exp(-2 * np.log(2) ** (1 / n) * (((x - x0) / dx)) ** (2 * n))
189
+ return out
190
+
191
+
192
+ def gauss2D(x, x0, dx, y, y0, dy, n=1, angle=0):
193
+ """
194
+ compute the 2D gaussian function along a vector x, centered in x0 and with a
195
+ FWHM in intensity of dx and smae along y axis. n=1 is for the standard gaussian while n>1 defines
196
+ a hypergaussian. optionally rotate it by an angle in degree
197
+
198
+ Parameters
199
+ ----------
200
+ x: (ndarray) first axis of the 2D gaussian
201
+ x0: (float) the central position of the gaussian
202
+ dx: (float) :the FWHM of the gaussian
203
+ y: (ndarray) second axis of the 2D gaussian
204
+ y0: (float) the central position of the gaussian
205
+ dy: (float) :the FWHM of the gaussian
206
+ n=1 : an integer to define hypergaussian, n=1 by default for regular gaussian
207
+ angle: (float) a float to rotate main axes, in degree
208
+
209
+ Returns
210
+ -------
211
+ out : ndarray 2 dimensions
212
+
213
+ """
214
+ if angle == 0:
215
+ data = np.transpose(np.outer(gauss1D(x, x0, dx, n), gauss1D(y, y0, dy, n)))
216
+
217
+ else:
218
+
219
+ theta = np.radians(angle)
220
+ c, s = np.cos(theta), np.sin(theta)
221
+ R = np.array(((c, -s), (s, c)))
222
+ (x0r, y0r) = tuple(R.dot(np.array([x0, y0])))
223
+
224
+ data = np.zeros((len(y), len(x)))
225
+
226
+ for indx, xtmp in enumerate(x):
227
+ for indy, ytmp in enumerate(y):
228
+ rotatedvect = R.dot(np.array([xtmp, ytmp]))
229
+ data[indy, indx] = gauss1D(rotatedvect[0], x0r, dx, n) * gauss1D(rotatedvect[1], y0r, dy, n)
230
+
231
+ return data
232
+
233
+
234
+ def rotate2D(origin:tuple = (0,0), point:tuple = (0,0), angle:float = 0):
235
+ """
236
+ Rotate a point counterclockwise by a given angle around a given origin.
237
+
238
+ The angle should be given in radians.
239
+ Parameters
240
+ ----------
241
+ origin: (tuple) x,y coordinate from which to rotate
242
+ point: (tuple) x,y coordinate of point to rotate
243
+ angle: (float) a float to rotate main axes, in radian
244
+
245
+ Returns
246
+ -------
247
+ out : (tuple) x,y coordinate of rotated point
248
+
249
+ """
250
+ ox, oy = origin
251
+ px, py = point
252
+
253
+ qx = ox + np.cos(angle) * (px - ox) - np.sin(angle) * (py - oy)
254
+ qy = oy + np.sin(angle) * (px - ox) + np.cos(angle) * (py - oy)
255
+ return qx, qy
256
+
257
+ def ftAxis(Npts, omega_max):
258
+ """
259
+ Given two numbers Npts,omega_max, return two vectors spanning the temporal
260
+ and spectral range. They are related by Fourier Transform
261
+
262
+ Parameters
263
+ ----------
264
+ Npts: (int)
265
+ A number of points defining the length of both grids
266
+ omega_max: (float)
267
+ The maximum circular frequency in the spectral domain. its unit defines
268
+ the temporal units. ex: omega_max in rad/fs implies time_grid in fs
269
+
270
+ Returns
271
+ -------
272
+ omega_grid: (ndarray)
273
+ The spectral axis of the FFT
274
+ time_grid: (ndarray))
275
+ The temporal axis of the FFT
276
+ See Also
277
+ --------
278
+ ftAxis, ftAxis_time, ift, ft2, ift2
279
+ """
280
+ if not isinstance(Npts, int):
281
+ raise TypeError('n should be a positive integer, if possible power of 2')
282
+ elif Npts < 1:
283
+ raise ValueError('n should be a strictly positive integer')
284
+ dT = 2 * np.pi / (2 * omega_max)
285
+ omega_grid = np.linspace(-omega_max, omega_max, Npts)
286
+ time_grid = dT * np.linspace(-(Npts - 1) / 2, (Npts - 1) / 2, Npts)
287
+ return omega_grid, time_grid
288
+
289
+
290
+ def ftAxis_time(Npts, time_max):
291
+ """
292
+ Given two numbers Npts,omega_max, return two vectors spanning the temporal
293
+ and spectral range. They are related by Fourier Transform
294
+
295
+ Parameters
296
+ ----------
297
+ Npts : number
298
+ A number of points defining the length of both grids
299
+ time_max : number
300
+ The maximum tmporal window
301
+
302
+ Returns
303
+ -------
304
+ omega_grid : vector
305
+ The spectral axis of the FFT
306
+ time_grid : vector
307
+ The temporal axis of the FFT
308
+ See Also
309
+ --------
310
+ ftAxis, ftAxis_time, ift, ft2, ift2
311
+ """
312
+ if not isinstance(Npts, int):
313
+ raise TypeError('n should be a positive integer, if possible power of 2')
314
+ elif Npts < 1:
315
+ raise ValueError('n should be a strictly positive integer')
316
+ dT = time_max / Npts
317
+ omega_max = (Npts - 1) / 2 * 2 * np.pi / time_max
318
+ omega_grid = np.linspace(-omega_max, omega_max, Npts)
319
+ time_grid = dT * np.linspace(-(Npts - 1) / 2, (Npts - 1) / 2, Npts)
320
+ return omega_grid, time_grid
321
+
322
+
323
+ def ft(x, dim=-1):
324
+ """
325
+ Process the 1D fast fourier transform and swaps the axis to get coorect results using ftAxis
326
+ Parameters
327
+ ----------
328
+ x: (ndarray) the array on which the FFT should be done
329
+ dim: the axis over which is done the FFT (default is the last of the array)
330
+
331
+ Returns
332
+ -------
333
+ See Also
334
+ --------
335
+ ftAxis, ftAxis_time, ift, ft2, ift2
336
+ """
337
+ if not isinstance(dim, int):
338
+ raise TypeError('dim should be an integer specifying the array dimension over which to do the calculation')
339
+ assert isinstance(x, np.ndarray)
340
+ assert dim >= -1
341
+ assert dim <= len(x.shape) - 1
342
+
343
+ out = np.fft.fftshift(np.fft.fft(np.fft.fftshift(x, axes=dim), axis=dim), axes=dim)
344
+ return out
345
+
346
+
347
+ def ift(x, dim=0):
348
+ """
349
+ Process the inverse 1D fast fourier transform and swaps the axis to get correct results using ftAxis
350
+ Parameters
351
+ ----------
352
+ x: (ndarray) the array on which the FFT should be done
353
+ dim: the axis over which is done the FFT (default is the last of the array)
354
+
355
+ Returns
356
+ -------
357
+ See Also
358
+ --------
359
+ ftAxis, ftAxis_time, ift, ft2, ift2
360
+ """
361
+ if not isinstance(dim, int):
362
+ raise TypeError('dim should be an integer specifying the array dimension over which to do the calculation')
363
+ assert isinstance(x, np.ndarray)
364
+ assert dim >= -1
365
+ assert dim <= len(x.shape) - 1
366
+ out = np.fft.fftshift(np.fft.ifft(np.fft.fftshift(x, axes=dim), axis=dim), axes=dim)
367
+ return out
368
+
369
+
370
+ def ft2(x, dim=(-2, -1)):
371
+ """
372
+ Process the 2D fast fourier transform and swaps the axis to get correct results using ftAxis
373
+ Parameters
374
+ ----------
375
+ x: (ndarray) the array on which the FFT should be done
376
+ dim: the axis over which is done the FFT (default is the last of the array)
377
+
378
+ Returns
379
+ -------
380
+ See Also
381
+ --------
382
+ ftAxis, ftAxis_time, ift, ft2, ift2
383
+ """
384
+ assert isinstance(x, np.ndarray)
385
+ if hasattr(dim, '__iter__'):
386
+ for d in dim:
387
+ if not isinstance(d, int):
388
+ raise TypeError(
389
+ 'elements in dim should be an integer specifying the array dimension over which to do the calculation')
390
+ assert d <= len(x.shape)
391
+ else:
392
+ if not isinstance(dim, int):
393
+ raise TypeError(
394
+ 'elements in dim should be an integer specifying the array dimension over which to do the calculation')
395
+ assert dim <= len(x.shape)
396
+ out = np.fft.fftshift(np.fft.fft2(np.fft.fftshift(x, axes=dim)), axes=dim)
397
+ return out
398
+
399
+
400
+ def ift2(x, dim=(-2, -1)):
401
+ """
402
+ Process the inverse 2D fast fourier transform and swaps the axis to get correct results using ftAxis
403
+ Parameters
404
+ ----------
405
+ x: (ndarray) the array on which the FFT should be done
406
+ dim: the axis (or a tuple of axes) over which is done the FFT (default is the last of the array)
407
+
408
+ Returns
409
+ -------
410
+ See Also
411
+ --------
412
+ ftAxis, ftAxis_time, ift, ft2, ift2
413
+ """
414
+ assert isinstance(x, np.ndarray)
415
+ if hasattr(dim, '__iter__'):
416
+ for d in dim:
417
+ if not isinstance(d, int):
418
+ raise TypeError(
419
+ 'elements in dim should be an integer specifying the array dimension over which to do the calculation')
420
+ assert d <= len(x.shape)
421
+ else:
422
+ if not isinstance(dim, int):
423
+ raise TypeError(
424
+ 'elements in dim should be an integer specifying the array dimension over which to do the calculation')
425
+ assert dim <= len(x.shape)
426
+ out = np.fft.fftshift(np.fft.ifft2(np.fft.fftshift(x, axes=dim)), axes=dim)
427
+ return out
428
+
429
+
430
+ def flatten(xs):
431
+ """Flatten nested list"""
432
+ for x in xs:
433
+ if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
434
+ yield from flatten(x)
435
+ else:
436
+ yield x
437
+
438
+ class LSqEllipse:
439
+
440
+ def fit(self, data):
441
+ """Lest Squares fitting algorithm
442
+
443
+ Theory taken from (*)
444
+ Solving equation Sa=lCa. with a = |a b c d f g> and a1 = |a b c>
445
+ a2 = |d f g>
446
+
447
+ Args
448
+ ----
449
+ data (list:list:float): list of two lists containing the x and y data of the
450
+ ellipse. of the form [[x1, x2, ..., xi],[y1, y2, ..., yi]]
451
+
452
+ Returns
453
+ ------
454
+ coef (list): list of the coefficients describing an ellipse
455
+ [a,b,c,d,f,g] corresponding to ax**2+2bxy+cy**2+2dx+2fy+g
456
+ """
457
+ x, y = numpy.asarray(data, dtype=float)
458
+
459
+ # Quadratic part of design matrix [eqn. 15] from (*)
460
+ D1 = numpy.mat(numpy.vstack([x ** 2, x * y, y ** 2])).T
461
+ # Linear part of design matrix [eqn. 16] from (*)
462
+ D2 = numpy.mat(numpy.vstack([x, y, numpy.ones(len(x))])).T
463
+
464
+ # forming scatter matrix [eqn. 17] from (*)
465
+ S1 = D1.T * D1
466
+ S2 = D1.T * D2
467
+ S3 = D2.T * D2
468
+
469
+ # Constraint matrix [eqn. 18]
470
+ C1 = numpy.mat('0. 0. 2.; 0. -1. 0.; 2. 0. 0.')
471
+
472
+ # Reduced scatter matrix [eqn. 29]
473
+ M = C1.I * (S1 - S2 * S3.I * S2.T)
474
+
475
+ # M*|a b c >=l|a b c >. Find eigenvalues and eigenvectors from this equation [eqn. 28]
476
+ eval, evec = numpy.linalg.eig(M)
477
+
478
+ # eigenvector must meet constraint 4ac - b^2 to be valid.
479
+ cond = 4 * numpy.multiply(evec[0, :], evec[2, :]) - numpy.power(evec[1, :], 2)
480
+ a1 = evec[:, numpy.nonzero(cond.A > 0)[1]]
481
+
482
+ # |d f g> = -S3^(-1)*S2^(T)*|a b c> [eqn. 24]
483
+ a2 = -S3.I * S2.T * a1
484
+
485
+ # eigenvectors |a b c d f g>
486
+ self.coef = numpy.vstack([a1, a2])
487
+ self._save_parameters()
488
+
489
+ def _save_parameters(self):
490
+ """finds the important parameters of the fitted ellipse
491
+
492
+ Theory taken form http://mathworld.wolfram
493
+
494
+ Args
495
+ -----
496
+ coef (list): list of the coefficients describing an ellipse
497
+ [a,b,c,d,f,g] corresponding to ax**2+2bxy+cy**2+2dx+2fy+g
498
+
499
+ Returns
500
+ _______
501
+ center (List): of the form [x0, y0]
502
+ width (float): major axis
503
+ height (float): minor axis
504
+ phi (float): rotation of major axis form the x-axis in radians
505
+ """
506
+
507
+ # eigenvectors are the coefficients of an ellipse in general form
508
+ # a*x^2 + 2*b*x*y + c*y^2 + 2*d*x + 2*f*y + g = 0 [eqn. 15) from (**) or (***)
509
+ a = self.coef[0, 0]
510
+ b = self.coef[1, 0] / 2.
511
+ c = self.coef[2, 0]
512
+ d = self.coef[3, 0] / 2.
513
+ f = self.coef[4, 0] / 2.
514
+ g = self.coef[5, 0]
515
+
516
+ # finding center of ellipse [eqn.19 and 20] from (**)
517
+ x0 = (c * d - b * f) / (b ** 2. - a * c)
518
+ y0 = (a * f - b * d) / (b ** 2. - a * c)
519
+
520
+ # Find the semi-axes lengths [eqn. 21 and 22] from (**)
521
+ numerator = 2 * (a * f * f + c * d * d + g * b * b - 2 * b * d * f - a * c * g)
522
+ denominator1 = (b * b - a * c) * ((c - a) * numpy.sqrt(1 + 4 * b * b / ((a - c) * (a - c))) - (c + a))
523
+ denominator2 = (b * b - a * c) * ((a - c) * numpy.sqrt(1 + 4 * b * b / ((a - c) * (a - c))) - (c + a))
524
+ width = numpy.sqrt(numerator / denominator1)
525
+ height = numpy.sqrt(numerator / denominator2)
526
+
527
+ # angle of counterclockwise rotation of major-axis of ellipse to x-axis [eqn. 23] from (**)
528
+ # or [eqn. 26] from (***).
529
+ phi = .5 * numpy.arctan((2. * b) / (a - c))
530
+
531
+ self._center = [x0, y0]
532
+ self._width = width
533
+ self._height = height
534
+ self._phi = phi
535
+
536
+ @property
537
+ def center(self):
538
+ return self._center
539
+
540
+ @property
541
+ def width(self):
542
+ return self._width
543
+
544
+ @property
545
+ def height(self):
546
+ return self._height
547
+
548
+ @property
549
+ def phi(self):
550
+ """angle of counterclockwise rotation of major-axis of ellipse to x-axis
551
+ [eqn. 23] from (**)
552
+ """
553
+ return self._phi
554
+
555
+ def parameters(self):
556
+ return self.center, self.width, self.height, self.phi
557
+
558
+
559
+ def make_test_ellipse(center=[1, 1], width=1, height=.6, phi=3.14 / 5):
560
+ """Generate Elliptical data with noise
561
+
562
+ Args
563
+ ----
564
+ center (list:float): (<x_location>, <y_location>)
565
+ width (float): semimajor axis. Horizontal dimension of the ellipse (**)
566
+ height (float): semiminor axis. Vertical dimension of the ellipse (**)
567
+ phi (float:radians): tilt of the ellipse, the angle the semimajor axis
568
+ makes with the x-axis
569
+
570
+ Returns
571
+ -------
572
+ data (list:list:float): list of two lists containing the x and y data of the
573
+ ellipse. of the form [[x1, x2, ..., xi],[y1, y2, ..., yi]]
574
+ """
575
+ t = numpy.linspace(0, 2 * numpy.pi, 1000)
576
+ x_noise, y_noise = numpy.random.rand(2, len(t))
577
+
578
+ ellipse_x = center[0] + width * numpy.cos(t) * numpy.cos(phi) - height * numpy.sin(t) * numpy.sin(
579
+ phi) + x_noise / 2.
580
+ ellipse_y = center[1] + width * numpy.cos(t) * numpy.sin(phi) + height * numpy.sin(t) * numpy.cos(
581
+ phi) + y_noise / 2.
582
+
583
+ return [ellipse_x, ellipse_y]
584
+
File without changes
@@ -0,0 +1,96 @@
1
+ #this is the configuration file of PyMoDAQ
2
+ [style]
3
+ darkstyle = true
4
+ syntax_highlighting = 'github-dark'
5
+ language = "English"
6
+ country = "UnitedStates"
7
+
8
+ [qtbackend]
9
+ backends = [ "pyqt5", "pyqt6", "pyside2", "pyside6",]
10
+ backend = "pyqt5"
11
+
12
+
13
+ [data_saving]
14
+ [data_saving.h5file]
15
+ save_path = "C:\\Data" #base path where data are automatically saved
16
+ compression_level = 5 # for hdf5 files between 0(min) and 9 (max)
17
+
18
+ [data_saving.hsds] #hsds connection option (https://www.hdfgroup.org/solutions/highly-scalable-data-service-hsds/)
19
+ #to save data in pymodaq using hpyd backend towards distant server or cloud (mimicking hdf5 files)
20
+ root_url = "http://hsds.sebastienweber.fr"
21
+ username = "pymodaq_user"
22
+ pwd = "pymodaq"
23
+
24
+ [data_saving.data_type]
25
+ dynamic = 'float64' # choose from below. This will force the datatype to be saved to
26
+ dynamics = ['uint8', 'int8', 'uint16', 'int16', 'uint32', 'int32', 'uint64', 'int64', 'float64']
27
+
28
+
29
+ [general]
30
+ debug_level = "INFO" #either "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
31
+ debug_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
32
+ check_version = true # automatically check version at startup (or not if False)
33
+ message_status_persistence = 1000 # ms
34
+
35
+ hdf5_backend = 'tables' # could be among ['tables', 'h5py', 'h5pyd'], mostly tested with tables
36
+
37
+ [user]
38
+ name = "User name" # default name used as author in the hdf5 saving files
39
+
40
+
41
+ [plotting]
42
+ backend = 'matplotlib' # either 'matplotlib' or 'qt' or any other custom backend
43
+ plot_colors = [[255, 255, 255], [255, 0, 0], [0, 255, 0], [0, 0, 255], [14, 207, 189], [207, 14, 166], [207, 204, 14]]
44
+
45
+ [network]
46
+ [network.logging]
47
+ [network.logging.user]
48
+ username = "pymodaq_user"
49
+ pwd = "pymodaq"
50
+
51
+ [network.logging.sql] #location of the postgresql database server and options where the DAQ_Logger will log data
52
+ ip = "10.47.3.22"
53
+ port = 5432
54
+
55
+ [network.tcp-server]
56
+ ip = "10.47.0.39"
57
+ port = 6341
58
+
59
+ [network.leco-server]
60
+ run_coordinator_at_startup = false
61
+ host = "localhost"
62
+ port = 12300 # pyleco default Coordinator port
63
+
64
+ [presets]
65
+ default_preset_for_scan = "preset_default"
66
+ default_preset_for_logger = "preset_default"
67
+ default_preset_for_pid = "beam_steering_mock"
68
+
69
+ [actuator]
70
+ epsilon_default = 1
71
+ polling_interval_ms = 100 # ms Careful when using TCP/IP connection as you can saturate the connection with too much polling
72
+ polling_timeout_s = 20 # s
73
+ refresh_timeout_ms = 500 # ms
74
+ timeout = 10000 # default duration in ms to wait for data to be acquirred
75
+ siprefix = true # tell if printing of current value use a SI prefix or not (µ, m, k, M...)
76
+ display_units = true # display units in the SpinBoxes
77
+
78
+ [viewer]
79
+ daq_type = 'DAQ0D' #either "DAQ0D", "DAQ1D", "DAQ2D", "DAQND"
80
+ viewer_in_thread = true
81
+ timeout = 10000 # default duration in ms to wait for data to be acquirred
82
+ allow_settings_edition = false
83
+
84
+ [scan]
85
+ scan_in_thread = true
86
+ show_popups = true
87
+ default = "Scan2D"
88
+ Naverage = 1 # minimum is 1
89
+ steps_limit = 1000 # the limit of the number of steps you can set in a given scan
90
+ sort1D = true
91
+
92
+ [scan.timeflow]
93
+ wait_time = 0
94
+ wait_time_between = 0
95
+ timeout = 10000 # in millisecond
96
+