CCD-detektorok jegyzőkönyv

A mérés előkészítése

A laborvezető segítésével kapcsolja be az SBIG ST-5 CCD-kamera vezérlőegységét, majd a mérőgépen futó terminálablakban indítsa el a kamera Jupyterből való vezérlését lehetővé tevő szerverprogramot a következő paranccsal:

cd /labor/ccd/
./server.sh

A parancs futtatása után a program kiírja a képernyőre a CCD-kamera aktuális állapotát. Ezek után csatlakozzon a kamerához a Jupyterből a következő néhány cella lefuttatásával. Amennyiben a csatlakozás néhány másodpercen belül sikertelen, úgy végezze el az alábbi lépéseket:

  • A Kernel/Interrupt paranccsal szakítsa meg a jupyter futásását
  • Ctrl+C-vel lépjen ki a szerverprogramomból
  • A reset gomb megnyomásával indítsa újra a CCD-kamera vezérlőegységét
  • Indítsa újra a szerverprogramot

Ügyeljen arra, hogy a kamera műveleiteinek megszakítása (interrupt kernel) a kamera újraindítását igényelheti!

Ügyeljen arra, hogy a jegyzőköny adatai a cellák újrafuttatásakor elveszhetnek. A mért adatokat mindig mentse a savetxt(file) paranccsal!

In [1]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib
In [2]:
import sys
import time
import sbigpy
import scipy.optimize
In [3]:
st5 = sbigpy.ST5("tcp://157.181.168.75:3333")
st5.open()
In [4]:
st5.print_status()
ROM version: v2.1
CPU version: 1
CPU: 1
Firmware version: 258
Name: SBIG ST-5 CCD Camera
Shutter: 0
Needs offset: 0
DCS: 0
DCR: 0
Temp control supported: 1
Max TE drive: 1900
Image width: 320
Image height: 240
Read out modes:
--- Mode 0: ---
Mode: 0
Width: 320
Height: 240
Gain: 352
Pixel width: 4096
Pixel height: 4096
--- Mode 1: ---
Mode: 1
Width: 160
Height: 120
Gain: 800
Pixel width: 8192
Pixel height: 8192
--- -------- ---
Temp control enabled: 1
Temp setpoint: 2435
Temp output drive: 0
Temp sample rate: 30
Temp p_gain: 820
Temp i_gain: 164
Temp brownout detected: 0
Temperature: 13.482452 °C

1. feladat: a CCD termosztátjának vizsgálata

1. a) - 5 pont

Bekapcsolás után az ST5 vezérlőegysége a CCD hőmérsékletét konstans értéken tartja. Az kamera detektorának °C egységekben mért aktuális hőmérsékletét az st5.get_temperature() függvénnyel olvashatja ki. Írjon egy rövid python scriptet, mely rövid időn keresztül, másodpercenkénti felbontással kiolvassa a kamera termisztorát! Készítsen ábrát a mérésről! Az egy másodperces várakozáshoz használja a time.sleep(sec) függvényt!

In [8]:
# Hőmérséklet kiolvasása
st5.get_temperature()
Out[8]:
13.49453389937993
In [20]:
# Mintavételezés
temperatures_1a = list()
for i in range(60):
    temperatures_1a += [ st5.get_temperature() ]
    time.sleep(1)
    
savetxt("temperatures_1a.txt", temperatures_1a)
In [21]:
# Ábrarajzolás
figsize(12, 8)
plot(temperatures_1a)
xlabel(r"idő $\left[ s \right]$", size=15)
ylabel(r"hőmérséklet $\left[^{\circ}C\right]$", size=15)
title("A CCD mért hőmérséklete az idő függvényében", size=21, y=1.03)
Out[21]:
Text(0.5,1.03,'A CCD mért hőmérséklete az idő függvényében')

Néhány python parancs segítségével számítsa ki a kapott mintából az átlagos hőmérsékletet és a hőmérséklet stabilitását (szórását)!

In [25]:
# számolás
print("A mért hőmérsékletértékek átlaga:", "%.3f" % mean(temperatures_1a), "°C")
print("A mért hőmérsékletértékek szórása:", "%.3f" % sqrt(var(temperatures_1a)), "°C")
A mért hőmérsékletértékek átlaga: 13.919 °C
A mért hőmérsékletértékek szórása: 0.010 °C

1. b) - 2 pont

A termosztát kapcsolási pontját az st5.set_temperature(celsius) függvény segítségével állíthatja be, a termosztát kikapcsolására pedig az st5.reset_temperature() függvény szolgál. Az alábbi cella lefuttatásával kapcsolja ki a termosztátot, majd az előző feladathoz hasonlóan rövid ideig mintavételezze a hőmérsékletet. Az eredményről készítsen ábrát!

In [23]:
# mérés
st5.reset_temperature()
temperatures_1b = list()
for i in range(60):
    temperatures_1b += [ st5.get_temperature() ]
    time.sleep(1)
    
savetxt("temperatures_1b.txt", temperatures_1b)
In [30]:
# ábra
figsize(12, 8)
plot(temperatures_1b)
xlabel(r"idő $\left[ s \right]$", size=15)
ylabel(r"hőmérséklet $\left[^{\circ}C\right]$", size=15)
title("A CCD mért hőmérséklete az idő függvényében, kikapcsolt termosztát mellett", size=21, y=1.03)
Out[30]:
Text(0.5,1.03,'A CCD mért hőmérséklete az idő függvényében, kikapcsolt termosztát mellett')

1. c) - 3 pont

Hűtse le a CCD-t -5 °C-ra! A hűtési folyamat során folyamatosan olvassa ki a termiszor pillanatnyi értékét! Ábrázolja a hőmérséklet változását a hűtési folyamat során! Mennyi idő elteltével tekinthető megfelelően stabilnak a detektor hőmérséklete? A hűtési folyamat milyen jellegzetessége figyelhető meg? Mi lehet ennek az oka?

In [31]:
# mérés
st5.set_temperature(-5)
temperatures_1c = list()
for i in range(180):
    temperatures_1c += [ st5.get_temperature() ]
    time.sleep(1)
    
savetxt("temperatures_1c.txt", temperatures_1c)
In [32]:
# ábra
figsize(12, 8)
plot(temperatures_1c)
xlabel(r"idő $\left[ s \right]$", size=15)
ylabel(r"hőmérséklet $\left[^{\circ}C\right]$", size=15)
title("A CCD mért hőmérséklete az idő függvényében a hűtés során", size=21, y=1.03)
Out[32]:
Text(0.5,1.03,'A CCD mért hőmérséklete az idő függvényében a hűtés során')
In [48]:
# válaszok
avg_1c = mean(temperatures_1c[100:])
sig_1c = sqrt(var(temperatures_1c[100:]))
t_c = 0
for t in range(180):
    if abs(temperatures_1c[t] - avg_1c) > 5*sig_1c:
        tc = t
        
tc
Out[48]:
69

Válaszok

Az ábráról látszik, hogy valahol 50 s utántól lesz stabil a hőmérséklet. Hogy ezt számszerűsítserm, kiszámoltam, mennyi a hőmérsékletértékek átlaga és szórása 100 s után (amikor már egész biztosan stabil), és megkerestem azt a legkésőbbi időpontot, amikor a hőmérséklet az átlagtól a szórás 5-szörösénél jobban eltér. Ez a fenti számolás alapján 69 s-nál volt, tehát azt mondhatjuk, hogy a hűtés bekapcsolása után 70 s-tól már stabilnak tekinthető a rendszer hőmérséklete.

Az ábrán az a jellegzetesség figyelhető meg, hogy a CCD először lehűl 5°C alá, és utána melegedik vissza a beállított hőmérsékletre. A jelenség valószínűleg azért van, mert a hőmérsékletet egy termosztát szabályozza, ami akkor állítja le a hűtést/fűtést, amikor a rendszer már elérte a kívánt hőmérsékletet, de mivel ekkorra a Peltier-elemben már kialakult hőmérsékletkülönbség van, ez tovább hűti a CCD-t. Amikor pedig lesüllyedt a hőmérséklet 5°C alá, a Peltier elem átáll melegítésre, de mivel ilyenkor már rövidebb ideig melegít, fölfelé már nem lesz akkora túlllépés.

1. d) - 5 pont

Kapcsolja ki a termosztátot, és mérje ki a detektor melegedési görbéjét. Milyen időállandóval történik a melegedés?

In [33]:
# mérés
st5.reset_temperature()
temperatures_1d = list()
for i in range(120):
    temperatures_1d += [ st5.get_temperature() ]
    time.sleep(1)
    
savetxt("temperatures_1d.txt", temperatures_1d)
In [34]:
# ábra
figsize(12, 8)
plot(temperatures_1d)
xlabel(r"idő $\left[ s \right]$", size=15)
ylabel(r"hőmérséklet $\left[^{\circ}C\right]$", size=15)
title("A CCD mért hőmérséklete az idő függvényében a melegedés során", size=21, y=1.03)
Out[34]:
Text(0.5,1.03,'A CCD mért hőmérséklete az idő függvényében a melegedés során')
In [66]:
# időállandó meghatározása
def convergence(t, Too, T0, tau):
    """
    Implements the T(t) = Too + T0 * exp(- t/tau) function
    """
    return Too + T0 * exp(-t/tau)

par, cov = scipy.optimize.curve_fit(convergence, linspace(10, 119, 110), temperatures_1d[10:])

print("Az illesztett exponenciális függvény paraméterei:\n" + 
        "\tToo = " + "%.2f" % par[0] + "°C \u00b1 " + "%.2f" % sqrt(cov[0, 0]) + "°C\n" +
        "\tT0 = " + "%.2f" % par[1] + "°C \u00b1 " + "%.2f" % sqrt(cov[1, 1]) + "°C\n" +
        "\ttau = " + "%.2f" % par[2] + "s \u00b1 " + "%.2f" % sqrt(cov[2, 2]) + "s (Tehát ennyi az időállandó)"  )
Az illesztett exponenciális függvény paraméterei:
	Too = 21.22°C ± 0.02°C
	T0 = -34.79°C ± 0.15°C
	tau = 19.77s ± 0.10s (Tehát ennyi az időállandó)

2. feladat: CCD termikus zajának és forró pixeleinek vizsgálata

A CCD-detektor termikus tulajdonságainak vizsgálatához és az ún. 'dark' képek elkészítéséhez zárja le a kamera nyílását. Felvételt az st5.take_image(cs) függvény segítségével készíthet, ahol a cs paraméter az expozíciós időt jelenti századmásodpercben. Az elkészült képet az st5.read_image() függvény segítsével lehet a vezérlőegységről letölteni. A detektor hőmérsékletét az st5.get_temperature() függvénnyel lehet kiolvasni.

2. a) - 2 pont

A termosztát kikapcsolt állapota mellett zárja le a kamera nyílását és készítsen egy néhány másodperc expozíciós idejű felvételt. Jegyezze fel az expozíciós időt, és a detektor hőmérsékletét! Az elkészült képet az imshow(img, cmap='gray') függvény segítségével szürkeárnyalatos képként ábrázolhatja. Az ábrázolási tartomány az imshow függvény vmin és vmax paramétereivel állítható be.

In [69]:
# mérés
cs = 500
T_2a = st5.get_temperature()
st5.take_image(cs)
img_2a = st5.read_image()
savetxt("img_2a.txt", img_2a)
print("Az exponálási idő: " + str(cs/100) + "s\nACCD hőmérséklete: " + "%.2f" % T_2a + "°C")
Downloading image: ++++++++++++++++++++++++++++++++++++++++
Az exponálási idő: 5.0s
ACCD hőmérséklete: 21.61°C
In [73]:
# kép ábrázolása
imshow(img_2a, cmap="gray")
title(str(cs/100) + "s exponálási idővel, " + "%.1f" % T_2a + "°C\nhőmérsékleten készült 'dark' kép", size=18, y=1.03)
Out[73]:
Text(0.5,1.03,"5.0s exponálási idővel, 21.6°C\nhőmérsékleten készült 'dark' kép")

2. b) - 3 pont

Készítse el az előző feladatban felvett kép pixelintezitás-hisztogramját! Ábrázolja a hisztogramot úgy, hogy a termikus zaj, illetve a forró pixelek is látszódjanak! Határozza meg a pixelek átlagos értékét és a zaj mértékét. Végezze el a számítást a forró pixelek kiszűrésével is! A tengelyek skálázásánál ügyeljen arra, hogy a kamera A/D konvertere 14 bites.

In [91]:
# hisztogram készítés
_cnt, _edg = histogram(img_2a.ravel(), bins = 2**14, range = [0, 2**14-1])
In [94]:
# hisztogram ábra
step(.5*(_edg[1:]+_edg[:-1]), _cnt)
xlabel("beütésszám", size=13)
ylabel("pixelek száma", size=13)
title("A pixelintenzitás hisztogramja", size=18 , y=1.02)
Out[94]:
Text(0.5,1.02,'A pixelintenzitás hisztogramja')
In [4]:
# átlagos érték és zaj
print("A betütések átlagos értéke ", mean(img_2a.ravel()), "\nA Poisson-zaj (nem tudom, hogy ez kell-e, mert a kérdésemre sem mondták meg, de a jegyzet alapján ez tűnik legvalószínűbbnek)", sqrt(mean(img_2a.ravel())) )
print("Ha nem számoljuk a forró pixeleket, a betütések átlagos értéke ", mean(img_2a.ravel()[where(img_2a.ravel() < 1000)]), "\na Poisson-zaj", sqrt(mean(img_2a.ravel()[where(img_2a.ravel() < 1000)])) )
A betütések átlagos értéke  744.215234375 
A Poisson-zaj (nem tudom, hogy ez kell-e, mert a kérdésemre sem mondták meg, de a jegyzet alapján ez tűnik legvalószínűbbnek) 27.280308546184003
Ha nem számoljuk a forró pixeleket, a betütések átlagos értéke  608.026764527344 
a Poisson-zaj 24.658198728360997
In [121]:
a = array([1, 2, 5, 3 ,7, 4,3])
In [124]:
a[where(a < 4)]
Out[124]:
array([1, 2, 3, 3])

2. c) - 5 pont

Ismételje meg az előző mérést különböző expozíciós időkkel, illetve a kamera termosztátjának különböző beállításai mellett. Ügyeljen arra, hogy a termosztátnak jelentős időbe telik, mire stabilizálja a detektor hőmérsékletét! A hőmérsékletet érdemes 15 °C körüli értékről indulva folyamatosan csökkenteni. Rajzolja fel a képeket, és ábrázolja a hisztogrammokat. Határozza meg az egyes képek zaját. Hogyan függ a pixelek zaja a hőmérséklettől és az expozíciós időtől?

In [102]:
# mérés
imgs_cs = list()
for cs in range(100, 601, 100):
    st5.take_image(cs)
    imgs_cs += [ st5.read_image()]
    savetxt("img_cs_"+str(cs)+".txt", imgs_cs[-1])
    
cs = 200
imgs_T = list()
for T in range(15, -6, -5):
    print(T, "a") # checking
    st5.set_temperature(T)
    print(T, "b") # checking
    time.sleep(50)
    print(T, "c") # checking
    st5.take_image(cs)
    imgs_T += [st5.read_image() ]
    savetxt("img_T_"+str(T)+".txt", imgs_T[-1])
    print(T, "d") # checking
15 a
15 b
15 c
Downloading image: ++++++++++++++++++++++++++++++++++++++++
15 d
10 a
10 b
10 c
Downloading image: ++++++++++++++++++++++++++++++++++++++++
10 d
5 a
5 b
5 c
Downloading image: ++++++++++++++++++++++++++++++++++++++++
5 d
0 a
0 b
0 c
Downloading image: ++++++++++++++++++++++++++++++++++++++++
0 d
-5 a
-5 b
-5 c
Downloading image: ++++++++++++++++++++++++++++++++++++++++
-5 d
In [106]:
# képek
for i in range(6):
    figure()
    imshow(imgs_cs[i], cmap="gray")
    title("szobahőmérséklet, " + str(i + 1) + "s exponálás")
    
for i in range(5):
    figure()
    imshow(imgs_T[i], cmap="gray")
    title(str(15-i*5) + "°C, 2s exponálás")
In [119]:
# hisztogramok
figure()
for i in range(6):
    _cnt, _edg = histogram(imgs_cs[i].ravel(), bins = 2**14, range = [0, 2**14-1])
    step(.5*(_edg[201:1001]+_edg[200:1000]), _cnt[200:1000], label=str(i+1)+"s exponálás")
    xlabel("beütésszám", size=13)
    ylabel("pixelek száma", size=13)
    legend()
    title("szobahőmérsékleten, különböző exponálási idők mellett", size=18 , y=1.02)
    
figure()
for i in range(5):
    _cnt, _edg = histogram(imgs_T[i].ravel(), bins = 2**14, range = [0, 2**14-1])
    step(.5*(_edg[151:451]+_edg[150:450]), _cnt[150:450], label=str(15-5*i) + "°C")
    xlabel("beütésszám", size=13)
    ylabel("pixelek száma", size=13)
    legend()
    title("különböző hőmérséklete, 2s exponálás idő mellett", size=18 , y=1.02)
In [8]:
# számolás
atlag_cs = [ mean(imgs_cs[i]) for i in range(6) ]
zaj_cs = [ sqrt(atlag_cs[i]) for i in range(6) ]
atlag_T = [ mean(imgs_T[i]) for i in range(5) ]
zaj_T = [ sqrt(atlag_T[i]) for i in range(5) ]
In [14]:
# zaj a hőmérséklet függvényében
figsize(12, 8)
plot(linspace(15, -5, 5), zaj_T, "o")
xlabel("hőmérséklet [°C]", size=13)
ylabel("Poisson-zaj", size=13)
title("Poisson-zaj a hőmérséklet függvényében", size=21, y=1.02)
Out[14]:
Text(0.5,1.02,'Poisson-zaj a hőmérséklet függvényében')
In [15]:
# zaj az integrálási idő függvényében
plot(linspace(1, 6, 6), zaj_cs, "o")
xlabel("integrálási idő [s]", size=13)
ylabel("Poisson-zaj", size=13)
title("Poisson-zaj az integrálási idő függvényében", size=21, y=1.02)
Out[15]:
Text(0.5,1.02,'Poisson-zaj az integrálási idő függvényében')

a mérés szöveges értékelése

A hőmérséklet függvényében gondolom exponenciálisan emelkedik a zaj a Boltzman-eloszlás miatt, az integrálási idő függvényében én azt várnám, hogy gyökösen fog, ami akár lehetséges is ez alapján az ábra alapján.

3. feladat - kalibrált szürkeárnyalatos felvétel készítése

3. a) - 2 pont

Állítsa a szűrőváltot szűrő nélküli állásba és válasszon minimális (f/22) blendenyílást. Hűtse le a detektort -10 fokra, majd készítsen egy képet a méréshez tartozó apró bábuk valamelyikéről. Válasszon olyan expozíciós időt, hogy kihasználja a detektor dinamikatartományát, ugyanakkor a pixelek ne szaturálódjanak. Ha szükséges, a laborvezető segítségével állítson a fókuszon. Rajzolja fel a képet is az intenzitáshisztogramot!

A továbbiakban úgy nevezze el a változókat, hogy az összes elkészült kép a memóriában maradjon, mert szükség lesz rájuk. A képeket tartalmazó tömböket az np.save függvénnyel bináris fájlokba is mentse el!

In [123]:
# hőmérséklet beállítása
In [ ]:
# expozíció
In [ ]:
# kép felrajzolása
In [ ]:
# histogram felrajzolása

3. b) Flat kép készítése - 3 pont

Helyezzen egy papírlapot a kamera elé, és a 3. a) feladatban használt expozíciós idő és hőmérséklet mellett készítsen legalább 5 fókuszálatlan felvételt az egyenletesen megvilágított papírlapról. (Egyenként töltse le a képeket, hogy a kameraprocesszor belső buffere nehogy túlcsorduljon!) Átlagolja ki a képeket, majd ábrázolja!

In [ ]:
# felvételek készítése
In [154]:
# átlagolás
In [ ]:
# a kiátlagolt flat ábrázolása
In [ ]:
# tapasztalatok

3. c) - Dark kép készítése - 2 pont

Az előző kép még nyers, a detektor sötétáramát is tartalmazza. Ismét takarja el az objektív nyílását, és készítsen dark felvételeket az előzővel megegyező expozíciós idővel és detektorhőmérséklettel. Átlagoljon ki legalább 10 képet. Erre használhatja a kameraprocesszor belső bufferét az alábbi rövid script segítségével:

In [ ]:
# Dark kép rögzítése

N = 10
st5.clr_buf(sbigpy.ST5.BUFFER_ACCU)
for i in range(N):
    st5.take_image(50)
    st5.accum_image()
dark = st5.read_image(buffer=sbigpy.ST5.BUFFER_ACCU)
dark = dark / N
In [ ]:
# kép felrajzolása
In [ ]:
# hisztogram
In [ ]:
# tapasztalatok

3. d) - Bias kép készítése - 2 pont

Az előző feladathoz hasonlóan, eltakart detektorállás mellett készítsen bias felvételeket, melyből a detektor pixeleinek nullponti értékei határozhatók meg. A felvételeket minimális, 1/100 másodperces idővel készítse.

In [ ]:
# Bias kép rögzítése

N = 10
st5.clr_buf(sbigpy.ST5.BUFFER_ACCU)
for i in range(N):
    st5.take_image(1)
    st5.accum_image()
bias = st5.read_image(buffer=sbigpy.ST5.BUFFER_ACCU)
bias = bias / N
In [ ]:
# kép felrajzolása
In [ ]:
# hisztogram
In [71]:
# tapasztalatok

3. e) Kép kalibrálása - 3 pont

Az $I = \frac{R - D}{F}$ formula alapján készítse el és ábrázolja a kalibrált képet. Hasonlítsa össze az eredetivel, és elemezze a tapasztalatokat!

In [157]:
# számolás
In [ ]:
# ábrázolás
In [ ]:
# hisztogram

4. feladat - színes felvétel készítése

4. a) - 3 pont

Készítsen a báburól egy-egy felvételt a három színszűrővel. Ügyeljen arra, hogy két expozíció között se a kamera, se a modell ne mozduljon el. Az előző feladatban megismert módon kalibrálja a képeket. Mindhárom színszűrő esetében használhatja a szűrő nélküli flat képeket.

In [ ]:
# felvételek elkészítése
In [169]:
# kalibráció
In [ ]:
# a három színcsatorna ábrázolása külön-külön

4. b) - 3 pont

Kombinálja össze a három színcsatornát színes RGB képpé! Ábrázolja a képet! Ügyeljen arra, hogy az imshow függvény csak uint8 típusú tömbökben tárolt színes képeket tud megjeleníteni. Elemezze a tapasztalatait. Milyen módon lehet meghatározni a három színcsatorna helyes keverési arányát?

In [200]:
# számolás
In [ ]:
# ábrázolás
In [ ]:
# tapasztalatok

A méréssel kapcsolatos észrevételek

Kitölteni nem kötelező:

  • Itt kérjük feltűntetni, hogy mennyi idő volt szükséges a feladatok elvégzéséhez.
  • Itt lehet javaslatot tenni a méréssel kapcsolatban.
  • A méréssel kapcsolatban felmerült további ötletek.

Észrevételezem, hogy 10 perc van hátra a 3 és fél órás laborból és a 43 pontnyi feladatból 25 pontnyit csináltam meg. Nem kezdek bel a hátralévőkbe, mert úgysem fejezem be, és nem akarok ezzel otthon foglalkozni. Jó lenne, ha a feladatokat jelentősen lecsökkentenék, gondolok itt elsősorban arra a részre, ahol vagy egy tucatnyi mérést kell csinálni. Én automatizáltam, hogy gyorsabb legyen, és nem is mértem sokat, mégis az utóbbi 2 órát (a laboridő több mint felét) a 2 c) feladattal töltöttem.

Ezen kívül jelentősen javítana a mérési esélyeken, ha a leírás lényegretörőbb lenne: 17 oldalas leírásból fél oldal az ami tényleg szükséges, 1-2 oldal az, ami a nem szükséges, de hasznos infó, a többin pedig amíg átrágom elsikkad minden lényeges információ (pláne, hogy az utolsó oldalakban van a lényeg).

Az előző két mérésemhez (fénysebesség, hang2) képest ez egy hatalmas visszaesés a követelmények teljesíthetősége (és a lelki nyugalmam kímélése) terén.