Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cta-array-elements
ccf
LIDAR_Analysis
Commits
71620795
Commit
71620795
authored
May 20, 2017
by
Markus Gaug
Browse files
script to calculate new calibration constants from monochromator output taken with a Hg lamp
parent
b296cd78
Pipeline
#6008
passed with stages
in 2 minutes and 30 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
hg_calibration.py
0 → 100644
View file @
71620795
#!/usr/bin/python
"""
A small analysis program for data taken with the polychromator from a Hg spectral lamp
The program read the lvm-file from input, fits 4 Gaussian peaks around the expected lines
and derives a linear regression between fitted and expected intensity peak positions.
The result is new calibration curve, including uncertainties
"""
import
sys
import
matplotlib
as
mpl
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
matplotlib.cbook
as
cbook
from
scipy
import
optimize
as
opt
from
scipy.optimize
import
curve_fit
file
=
str
(
sys
.
argv
[
1
])
print
(
file
)
# input file must contain (only) lines of type: \twavelength\tPindiodeCurrent
wloffset
=
0.
# 0: start calibration from lambda=0, otherwise choose wloffset as reference point
shift
=
-
6.5
# -3.5 for 1HgMarkus, -6.5 for 1HgCalcPere
window
=
5.
# fit ranges: (central wavelength + shift) +- window
invert
=
0
# 0: calibrate lambda_theor vs. lambda_meas 1: calibrate lambda_meas vs. lambda_theor
data
=
np
.
loadtxt
(
file
,
delimiter
=
'
\t
'
,
converters
=
{
0
:
lambda
s
:
float
(
s
.
strip
()
or
0
)})
x
=
data
[:,
1
]
y
=
data
[:,
2
]
xxorg
=
[
365.015
,
404.656
,
435.833
,
546.074
]
# from http://opticalengineering.spiedigitallibrary.org/article.aspx?articleid=1556406
xx
=
list
(
map
(
lambda
a
:
a
-
wloffset
,
xxorg
)
)
# [365.015-wloffset, 404.656-wloffset, 435.833-wloffset, 546.074-wloffset ]
xxerr
=
[
0.001
,
0.001
,
0.001
,
0.001
]
yy
=
[]
yyorg
=
[]
yyerr
=
[]
ww
=
[]
indices1
=
(
np
.
nonzero
((
x
>
xxorg
[
0
]
+
shift
-
window
)
&
(
x
<
xxorg
[
0
]
+
shift
+
window
)))
x1
=
x
[
indices1
]
y1
=
y
[
indices1
]
indices2
=
(
np
.
nonzero
((
x
>
xxorg
[
1
]
+
shift
-
window
)
&
(
x
<
xxorg
[
1
]
+
shift
+
window
)))
x2
=
x
[
indices2
]
y2
=
y
[
indices2
]
indices3
=
(
np
.
nonzero
((
x
>
xxorg
[
2
]
+
shift
-
window
)
&
(
x
<
xxorg
[
2
]
+
shift
+
window
)))
x3
=
x
[
indices3
]
y3
=
y
[
indices3
]
indices4
=
(
np
.
nonzero
((
x
>
xxorg
[
3
]
+
shift
-
window
)
&
(
x
<
xxorg
[
3
]
+
shift
+
window
)))
x4
=
x
[
indices4
]
y4
=
y
[
indices4
]
def
gaus
(
x
,
a
,
x0
,
sigma
):
return
a
*
np
.
exp
(
-
(
x
-
x0
)
**
2
/
(
2
*
sigma
**
2
))
f2
=
plt
.
subplot
(
211
)
f2
.
plot
(
x
,
y
,
'b+:'
,
label
=
'data'
)
popt
,
pcov
=
curve_fit
(
gaus
,
x1
,
y1
,
p0
=
[
2.5E-9
,
xxorg
[
0
]
+
shift
,
2.
])
print
(
pcov
)
f2
.
plot
(
x1
,
gaus
(
x1
,
*
popt
),
'ro:'
,
label
=
"1: %.1f nm (vs. %.1f nm)"
%
(
popt
[
1
],
xxorg
[
0
]))
yy
.
append
(
popt
[
1
]
-
wloffset
)
yyorg
.
append
(
popt
[
1
])
perr
=
np
.
sqrt
(
np
.
diag
(
pcov
))
#yyerr.append(perr[1])
yyerr
.
append
(
popt
[
2
]
/
np
.
sqrt
(
4.
))
ww
.
append
(
1.
/
yyerr
[
-
1
]
**
2
)
popt
,
pcov
=
curve_fit
(
gaus
,
x2
,
y2
,
p0
=
[
4.7E-9
,
xxorg
[
1
]
+
shift
,
2.
])
f2
.
plot
(
x2
,
gaus
(
x2
,
*
popt
),
'ro:'
,
label
=
"2: %.1f nm (vs. %.1f nm)"
%
(
popt
[
1
],
xxorg
[
1
]))
yy
.
append
(
popt
[
1
]
-
wloffset
)
yyorg
.
append
(
popt
[
1
])
perr
=
np
.
sqrt
(
np
.
diag
(
pcov
))
###print (perr)
#yyerr.append(perr[1])
yyerr
.
append
(
popt
[
2
]
/
np
.
sqrt
(
4.
))
ww
.
append
(
1.
/
yyerr
[
-
1
]
**
2
)
popt
,
pcov
=
curve_fit
(
gaus
,
x3
,
y3
,
p0
=
[
5.2E-9
,
xxorg
[
2
]
+
shift
,
2.
])
f2
.
plot
(
x3
,
gaus
(
x3
,
*
popt
),
'ro:'
,
label
=
"3: %.1f nm (vs. %.1f nm)"
%
(
popt
[
1
],
xxorg
[
2
]))
yy
.
append
(
popt
[
1
]
-
wloffset
)
yyorg
.
append
(
popt
[
1
])
perr
=
np
.
sqrt
(
np
.
diag
(
pcov
))
#print (perr)
#yyerr.append(perr[1])
yyerr
.
append
(
popt
[
2
]
/
np
.
sqrt
(
4.
))
ww
.
append
(
1.
/
yyerr
[
-
1
]
**
2
)
popt
,
pcov
=
curve_fit
(
gaus
,
x4
,
y4
,
p0
=
[
5.2E-9
,
xxorg
[
3
]
+
shift
,
2.
])
f2
.
plot
(
x4
,
gaus
(
x4
,
*
popt
),
'ro:'
,
label
=
"4: %.1f nm (vs. %.1f nm)"
%
(
popt
[
1
],
xxorg
[
3
]))
yy
.
append
(
popt
[
1
]
-
wloffset
)
yyorg
.
append
(
popt
[
1
])
perr
=
np
.
sqrt
(
np
.
diag
(
pcov
))
#print (perr)
#yyerr.append(perr[1])
yyerr
.
append
(
popt
[
2
]
/
np
.
sqrt
(
4.
))
ww
.
append
(
1.
/
yyerr
[
-
1
]
**
2
)
f2
.
legend
()
f2
.
set_title
(
"Hg Lamp"
)
f2
.
set_xlabel
(
'wavelength (nm)'
)
f2
.
set_ylabel
(
'Pin Diode current'
)
f3
=
plt
.
subplot
(
212
)
if
(
invert
):
m
,
b
=
np
.
polyfit
(
yy
,
xx
,
1
)
else
:
m
,
b
=
np
.
polyfit
(
xx
,
yy
,
1
)
def
wlinear_fit
(
xa
,
ya
,
w
)
:
"""
Fit (x,y,w) to a linear function, using exact formulae for weighted linear
regression. This code was translated from the GNU Scientific Library (GSL),
it is an exact copy of the function gsl_fit_wlinear.
"""
# compute the weighted means and weighted deviations from the means
# wm denotes a "weighted mean", wm(f) = (sum_i w_i f_i) / (sum_i w_i)
W
=
np
.
sum
(
w
)
wm_x
=
np
.
average
(
xa
,
weights
=
w
)
wm_y
=
np
.
average
(
ya
,
weights
=
w
)
dx
=
xa
-
wm_x
dy
=
ya
-
wm_y
wm_dx2
=
np
.
average
(
dx
**
2
,
weights
=
w
)
wm_dxdy
=
np
.
average
(
dx
*
dy
,
weights
=
w
)
# In terms of y = a + b x
b
=
wm_dxdy
/
wm_dx2
a
=
wm_y
-
wm_x
*
b
cov_00
=
(
1.0
/
W
)
*
(
1.0
+
wm_x
**
2
/
wm_dx2
)
cov_11
=
1.0
/
(
W
*
wm_dx2
)
cov_01
=
-
wm_x
/
(
W
*
wm_dx2
)
# Compute chi^2 = \sum w_i (y_i - (a + b * x_i))^2
# chi_2 = np.sum (w * ((ya-(a+b*xa))**2))
return
a
,
b
,
cov_00
,
cov_11
,
cov_01
aa
,
bb
,
cov_00
,
cov_11
,
cov_01
=
wlinear_fit
(
np
.
array
(
xx
),
np
.
array
(
yy
),
np
.
array
(
ww
))
#print (xx, yy, ww, yyerr)
chi2
=
0
for
i
in
range
(
len
(
xx
)):
print
(
yy
[
i
]
-
(
aa
+
bb
*
xx
[
i
]))
print
(
yyerr
[
i
])
chi2
+=
((
yy
[
i
]
-
(
aa
+
bb
*
xx
[
i
]))
/
yyerr
[
i
])
**
2
if
(
invert
):
f3
.
errorbar
(
np
.
array
(
yyorg
),
np
.
array
(
xxorg
),
np
.
array
(
xxerr
),
np
.
array
(
yyerr
),
'yo'
)
else
:
f3
.
errorbar
(
np
.
array
(
xxorg
),
np
.
array
(
yyorg
),
np
.
array
(
xxerr
),
np
.
array
(
yyerr
),
'yo'
)
if
(
wloffset
!=
0.
):
f3
.
plot
(
x
,
m
*
x
+
b
,
label
=
"(y-%.0f) = %.3f*(x-%.0f) + %.3f"
%
(
wloffset
,
m
,
wloffset
,
b
))
if
(
invert
):
f3
.
plot
(
x
,
1
/
bb
*
x
-
aa
/
bb
,
label
=
"(y-%.0f) = (%.4f$\pm$%.4f)*(x-%.0f) + (%.3f$\pm$%.3f), $\chi^{2}/NDF$=%.1f"
%
(
wloffset
,
1.
/
bb
,
np
.
sqrt
(
cov_11
),
wloffset
,
-
aa
/
bb
,
np
.
sqrt
(
cov_00
)
/
bb
,
chi2
/
2.
))
else
:
f3
.
plot
(
x
,
bb
*
x
+
aa
,
label
=
"(y-%.0f) = (%.4f$\pm$%.4f)*(x-%.0f) + (%.3f$\pm$%.3f), $\chi^{2}/NDF$=%.1f"
%
(
wloffset
,
bb
,
np
.
sqrt
(
cov_11
),
wloffset
,
aa
,
np
.
sqrt
(
cov_00
)
/
bb
,
chi2
/
2.
))
else
:
f3
.
plot
(
x
,
m
*
x
+
b
,
label
=
"y = %.3f*x + %.3f"
%
(
m
,
b
))
if
(
invert
):
f3
.
plot
(
x
,
1
/
bb
*
x
-
aa
/
bb
,
label
=
"y = (%.4f$\pm$%.4f)*x + (%.3f$\pm$%.3f), $\chi^{2}/NDF$=%.1f"
%
(
1.
/
bb
,
np
.
sqrt
(
cov_11
),
-
aa
/
bb
,
np
.
sqrt
(
cov_00
)
/
bb
,
chi2
/
2.
))
else
:
f3
.
plot
(
x
,
bb
*
x
+
aa
,
label
=
"y = (%.4f$\pm$%.4f)*x + (%.3f$\pm$%.3f), $\chi^{2}/NDF$=%.1f"
%
(
bb
,
np
.
sqrt
(
cov_11
),
aa
,
np
.
sqrt
(
cov_00
)
/
bb
,
chi2
/
2.
))
f3
.
legend
(
loc
=
"lower right"
)
#f3.set_title("Calibration")
if
(
invert
):
f3
.
set_ylabel
(
'wavelength expected (nm)'
)
f3
.
set_xlabel
(
'wavelength measured (nm)'
)
else
:
f3
.
set_xlabel
(
'wavelength expected (nm)'
)
f3
.
set_ylabel
(
'wavelength measured (nm)'
)
plt
.
show
()
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment