Skip to content

Commit bfbd69b

Browse files
committed
Merge commit 'e92bca0d6d5ae664606054b3ad33d0eb61a3dc86' into v0.6
2 parents f449265 + e92bca0 commit bfbd69b

21 files changed

+1295
-385
lines changed

core/util/units.py

Lines changed: 109 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
"""
2121

2222
import numpy as np
23-
import pyqtgraph.functions as fn
23+
try:
24+
import pyqtgraph.functions as fn
25+
except:
26+
fn = None
27+
import math
2428

2529

2630
def get_unit_prefix_dict():
@@ -47,9 +51,79 @@ def get_unit_prefix_dict():
4751
'E': 1e18,
4852
'Z': 1e21,
4953
'Y': 1e24
50-
}
54+
}
5155
return unit_prefix_dict
5256

57+
58+
class ScaledFloat(float):
59+
"""
60+
Format code 'r' for scaled output.
61+
62+
Examples
63+
--------
64+
>>> '{:.0r}A'.format(ScaledFloat(50))
65+
50 A
66+
>>> '{:.1r}A'.format(ScaledFloat(1.5e3))
67+
1.5 kA
68+
>>> '{:.1r}A'.format(ScaledFloat(2e-3))
69+
2.0 mA
70+
>>> '{:rg}A'.format(ScaledFloat(2e-3))
71+
2 mA
72+
>>> '{:rf}A'.format(ScaledFloat(2e-3))
73+
2.000000 mA
74+
"""
75+
76+
@property
77+
def scale(self):
78+
"""
79+
Returns the scale.
80+
81+
Examples
82+
--------
83+
1e-3: m
84+
1e6: M
85+
"""
86+
exponent = math.floor(math.log10(abs(self)) / 3)
87+
if exponent < -8:
88+
exponent = -8
89+
if exponent > 8:
90+
exponent = 8
91+
prefix = 'yzafpnum kMGTPEZY'
92+
return prefix[8 + exponent].strip()
93+
94+
def __format__(self, fmt):
95+
"""
96+
Fromats the string using format fmt.
97+
98+
r for scaled output.
99+
100+
Parameters
101+
----------
102+
fmt : str format string
103+
"""
104+
autoscale = False
105+
if (len(fmt) >= 2):
106+
if fmt[-2] == 'r':
107+
autoscale = True
108+
fmt = fmt[:-2] + fmt[-1]
109+
elif fmt[-1] == 'r':
110+
autoscale = True
111+
fmt = fmt[:-1] + 'f'
112+
elif fmt[-1] == 'r':
113+
autoscale = True
114+
fmt = fmt[:-1] + 'f'
115+
if (autoscale):
116+
scale = self.scale
117+
if (scale == 'u'):
118+
index = 'micro'
119+
else:
120+
index = scale
121+
value = self / get_unit_prefix_dict()[index]
122+
return '{:s} {:s}'.format(value.__format__(fmt), scale)
123+
else:
124+
return super().__format__(fmt)
125+
126+
53127
def create_formatted_output(param_dict, num_sig_digits=5):
54128
""" Display a parameter set nicely in SI units.
55129
@@ -86,45 +160,54 @@ def create_formatted_output(param_dict, num_sig_digits=5):
86160
87161
88162
"""
163+
if (fn is None):
164+
raise Exception('This function requires pyqtgraph.')
89165

90166
output_str = ''
91167
atol = 1e-18 # absolute tolerance for the detection of zero.
92168

93169
for entry in param_dict:
94170
if param_dict[entry].get('error') is not None:
95171

96-
value, error, digit = round_value_to_error(param_dict[entry]['value'], param_dict[entry]['error'])
97-
98-
if np.isclose(value, 0.0, atol=atol) or np.isnan(error) or np.isclose(error, 0.0, atol=atol) or np.isinf(error):
172+
value, error, digit = round_value_to_error(
173+
param_dict[entry]['value'], param_dict[entry]['error'])
99174

175+
if (np.isclose(value, 0.0, atol=atol)
176+
or np.isnan(error)
177+
or np.isclose(error, 0.0, atol=atol)
178+
or np.isinf(error)):
100179
sc_fact, unit_prefix = fn.siScale(param_dict[entry]['value'])
101-
str_val = '{0:.{1}e}'.format(param_dict[entry]['value'], num_sig_digits-1)
180+
str_val = '{0:.{1}e}'.format(
181+
param_dict[entry]['value'], num_sig_digits - 1)
102182
if np.isnan(np.float(str_val)):
103183
value = np.NAN
104184
elif np.isinf(np.float(str_val)):
105185
value = np.inf
106186
else:
107-
value = float('{0:.{1}e}'.format(param_dict[entry]['value'], num_sig_digits-1))
187+
value = float('{0:.{1}e}'.format(
188+
param_dict[entry]['value'], num_sig_digits - 1))
108189

109190
else:
110191
# the factor 10 moves the displayed digit by one to the right,
111192
# so that the values from 100 to 0.1 are displayed within one
112-
# range, rather then from the value 1000 to 1, which is default.
113-
sc_fact, unit_prefix = fn.siScale(error*10)
114-
193+
# range, rather then from the value 1000 to 1, which is
194+
# default.
195+
sc_fact, unit_prefix = fn.siScale(error * 10)
115196

116197
output_str += '{0}: {1} \u00B1 {2} {3}{4} \n'.format(entry,
117-
round(value*sc_fact, num_sig_digits-1),
118-
round(error*sc_fact, num_sig_digits-1),
198+
round(
199+
value * sc_fact, num_sig_digits - 1),
200+
round(
201+
error * sc_fact, num_sig_digits - 1),
119202
unit_prefix,
120-
param_dict[entry]['unit'],
203+
param_dict[entry][
204+
'unit'],
121205
)
122206

123207
else:
124208
output_str += '{0}: '.format(entry) + fn.siFormat(param_dict[entry]['value'],
125-
precision=num_sig_digits,
126-
suffix=param_dict[entry]['unit']) + '\n'
127-
209+
precision=num_sig_digits,
210+
suffix=param_dict[entry]['unit']) + '\n'
128211

129212
return output_str
130213

@@ -192,7 +275,7 @@ def round_value_to_error(value, error):
192275
# check if error is zero, since that is an invalid input!
193276
if np.isclose(error, 0.0, atol=atol) or np.isnan(error) or np.isinf(error):
194277
#self.log.error('Cannot round to the error, since either a zero error ')
195-
#logger.warning('Cannot round to the error, since either a zero error '
278+
# logger.warning('Cannot round to the error, since either a zero error '
196279
# 'value was passed for the number {0}, or the error is '
197280
# 'NaN: Error value: {1}. '.format(value, error))
198281

@@ -205,7 +288,7 @@ def round_value_to_error(value, error):
205288
log_val = np.log10(abs(error))
206289

207290
if log_val < 0:
208-
round_digit = -(int(log_val)-1)
291+
round_digit = -(int(log_val) - 1)
209292
else:
210293
round_digit = -(int(log_val))
211294

@@ -239,7 +322,7 @@ def get_relevant_digit(entry):
239322
return int(np.log10(entry))
240323
else:
241324
# catch the asymmetric behaviour of the log and int operation.
242-
return int(int(np.abs(np.log10(entry)))+1 + np.log10(entry)) - (int(np.abs(np.log10(entry))) +1)
325+
return int(int(np.abs(np.log10(entry))) + 1 + np.log10(entry)) - (int(np.abs(np.log10(entry))) + 1)
243326

244327

245328
def get_si_norm(entry):
@@ -253,11 +336,12 @@ def get_si_norm(entry):
253336
float normalization: the factor with which to divide the number.
254337
"""
255338
val = get_relevant_digit(entry)
256-
fact = int(val/3)
257-
power = int(3*fact)
339+
fact = int(val / 3)
340+
power = int(3 * fact)
258341
norm = 10**(power)
259342

260-
return entry/norm, norm
343+
return entry / norm, norm
344+
261345

262346
def is_number(test_value):
263347
""" Check whether passed value is a number
@@ -266,6 +350,7 @@ def is_number(test_value):
266350
"""
267351
return is_integer(test_value) or is_float(test_value) or is_complex(test_value)
268352

353+
269354
def is_integer(test_value):
270355
""" Check all available integer representations.
271356
@@ -276,13 +361,15 @@ def is_integer(test_value):
276361
np.uint, np.uint8, np.uint16, np.uint32,
277362
np.uint64]
278363

364+
279365
def is_float(test_value):
280366
""" Check all available float representations.
281367
282368
@return: bool, True if the passed value is a float, otherwise false.
283369
"""
284370
return type(test_value) in [np.float, np.float16, np.float32, np.float64]
285371

372+
286373
def is_complex(test_value):
287374
""" Check all available complex representations.
288375

documentation/changelog.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Changelog {#changelog}
2+
3+
## Relese 0.6
4+
5+
## Release 0.5
6+
7+
Released on 30 Dec 2015.
8+
Available at https://qosvn.physik.uni-ulm.de/svn/qudi/tags/release-0.5
9+
10+
Notes about this release are probably missing due to holidays.
11+
12+
* Two photon counters supported in NI card counter and counter logic
13+
14+
## Release 0.4
15+
16+
Released on 30.10.2015.
17+
Available at https://qosvn.physik.uni-ulm.de/svn/qudi/tags/release-0.4
18+
19+
New features:
20+
21+
* Tilted scanning
22+
* ODMR remembers settings
23+
* ODMR can save raw data
24+
* Working and tested support for Radiant Dyes flip mirrors
25+
* support for taking spectra from spectrometer via WinSpec32
26+
* POI positions are now actually updated when the tracked POI moves
27+
* remote module support is more robust now
28+
* fixed a crash when changing confocal color bar while scanning
29+
* winspec32 spectrometer support
30+
* configurable settling time at start of optimization scans
31+
* option for surface-subtraction in the depth optimization scan
32+
* ALPHA Task interface
33+
* PRE-ALPHA for pulsed experiments
34+
35+
## Release 0.3
36+
37+
Released on 31.07.2015. Available at https://qosvn.physik.uni-ulm.de/svn/qudi/tags/release-0.3
38+
39+
New features:
40+
41+
* Manager now includes log and iPython console
42+
* Manager can load and save the configuration
43+
* Manager can show active threads and remotely shared modules
44+
* QuDi remembers which configuration file is loaded
45+
* QuDi can restart to load new configuration
46+
* SmiQ R&S 06ATE works for ODMR
47+
* Dockwidgets in ODMR
48+
* Laser scanning with a remote wavemeter is now tested and confirmed working
49+
* Zoom with mouse in Confocal
50+
51+
Additionally, lots of bugs were fixed.
52+
53+
## Release 0.2
54+
55+
Release-0.2 is available since 07.07.2015.
56+
It can be found using: https://qosvn.physik.uni-ulm.de/svn/qudi/tags/release-0.2
57+
58+
New features:
59+
60+
* New Log style
61+
* (Manager shows module state)
62+
* Continues scan xy/depth (loop scan)
63+
* Rotate confocal images (rotates only the image, not the cursor!!!)
64+
* POI Manager GUI: restore default widget location (size might not be as default)
65+
* Cursor and arrow keys: right/left(x-direction) up/down(y-direction) Bild up/Bild down(z-direction); big step size with shift;step size can be changes in the settings
66+
* Clock time sample shift POI Manager
67+
* Centiles of colorbars is now working during a scan
68+
* All save files should now have the same time in the lable
69+
* duration of periodic optimiser changeable working during period
70+
* improved explanation in the data file of the Confocal scans
71+
* Added tooltips to Confocal and Optimiser settings
72+
73+
## Release 0.1
74+
75+
Release-0.1 is the first release of the QuDi software project.
76+
It can be found via SVN Checkout using this URL: https://qosvn.physik.uni-ulm.de/svn/qudi/tags/release-0.1
77+
It is possible to do basic measurements and the following modules are working:
78+
79+
* Counter
80+
* Confocal scanning
81+
* Laser scanning
82+
* POI managing
83+
* ODMR
84+
85+
The basics of all these modules are working but there is plenty room for improvement.
86+
At this stage the GUI is still under active development and so users should expect some interface items to change in future releases.
87+

documentation/main.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
* [License](@ref license)
5+
* [Changelog](@ref changelog)
56
* Setup
67
* [Installation](@ref installation)
78
* [Required packages](@ref required-python-packages)

0 commit comments

Comments
 (0)