Newer
Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 4 11:10:20 2019
@author: martindrech
"""
import numpy as np
from PyQt5 import QtCore
import threading
import time
from MCDAQcontrolsignals import anal_control_signal
from resources.messages import show_warning
from resources.scanFunctions import create_measurement_array, yield_array
Martin Drechsler
committed
from resources.storage import Storage
class CameraWorker(QtCore.QObject):
imageReadySignal = QtCore.pyqtSignal(np.ndarray, int)
measurementStartingSignal = QtCore.pyqtSignal()
measurementEndingSignal = QtCore.pyqtSignal()
Martin Drechsler
committed
def __init__(self, andor_camera):
Martin Drechsler
committed
self.cam = andor_camera
self.cam.Init()
print("camera worker initialized")
Martin Drechsler
committed
self.storage = Storage()
Martin Drechsler
committed
self.scan_array_gen = None
Martin Drechsler
committed
self._lock = threading.Lock()
Martin Drechsler
committed
def make_connections(self, frontend):
# frontend connections
frontend.cameraButton.clicked.connect(lambda: self.run(live_acq_params))
Martin Drechsler
committed
frontend.signalWithMeasurementParameters.connect(self.simple_scan_measurement_start)
Martin Drechsler
committed
frontend.roiDataReadySignal.connect(self.save_data_from_scan_step)
Martin Drechsler
committed
frontend.measurementFrame.saveMeasureButton.clicked.connect(
self.storage.permanent_save_current_data)
# internal connections
self.cam.helper.imageAquiredSignal.connect(self.new_image_acquired)
def __del__(self):
print("adios camera worker")
def run(self, params):
if self.cam.CameraAcquiring.getValue():
self._stop_acquisition_loop()
print("acquisition now stopping")
self._configure_acq_parameters(params)
self._start_acquisition_loop()
self.acq_thread = threading.Thread(
target=self.cam.live_acquisition_loop
)
self.acq_thread.start()
print("acquisiting now starting")
def _start_acquisition_loop(self):
self.cam.live_acquisition_configure()
self.cam.AcquisitionStart()
Martin Drechsler
committed
def _stop_acquisition_loop(self):
self.acq_thread.do_run = False
self.acq_thread.join()
self.cam.AcquisitionStop()
self.cam._flush()
def _configure_acq_parameters(self, params):
print('Acq parameters: ')
for p in params.children()[0].children():
print(p.name(), p.value())
params.child('Basic acq parameters').child('Camera name').setValue(
self.cam.CameraModel.getValue()
)
params.child('Basic acq parameters').child('Sensor Temperature').setValue(
self.cam.SensorTemperature.getValue()
)
params.child('Basic acq parameters').child('Temperature Status').setValue(
self.cam.TemperatureStatus.getString()
)
params.child('Basic acq parameters').child('Readout Time').setValue(
self.cam.ReadoutTime.getValue()
)
# setting camera parameteres according to tree
self.cam.ExposureTime.setValue(
params.child('Basic acq parameters').child('Exposure Time').value()
)
self.cam.FrameRate.setValue(self.cam.FrameRate.max())
params.child('Basic acq parameters').child('Frame Rate').setValue(
self.cam.AOIBinning.setString(
params.child('Basic acq parameters').child('Pixel Binning').value()
)
self.cam.PixelReadoutRate.setString(
params.child('Basic acq parameters').child('Pixel Readout Rate').value()
)
self.cam.SimplePreAmpGainControl.setString(
params.child('Basic acq parameters').child('Dynamic Range').value()
params.child('Basic acq parameters').child('Spurious Noise Filter').value()=='True'
def new_image_acquired(self, acq_index):
self.imageReadySignal.emit(self.cam.acq_queue.get(), acq_index)
Martin Drechsler
committed
def simple_scan_measurement_start(self, measure_params):
if self.cam.CameraAcquiring.getValue():
show_warning('Can not start measurement if camera is acquiring')
return 0
self.measurementStartingSignal.emit()
Martin Drechsler
committed
self.ao_to_scan = self.get_scan_signal(measure_params['signal_to_scan'])
start = measure_params['start']
end = measure_params['end']
step_num = measure_params['steps']
Martin Drechsler
committed
self.scan_array_gen = yield_array(create_measurement_array(start, end, step_num))
Martin Drechsler
committed
self.ao_to_scan.go_softly_to_value(start)
Martin Drechsler
committed
self.storage.set_directory(measure_params['directory'])
self.storage.create_data_file('Time', measure_params['signal_to_scan'], 'Roi data')
Martin Drechsler
committed
self.storage.append_metadata_to_current_file(measure_params['spinboxes_dict'], self.cam.GetMetaData(), measure_params)
Martin Drechsler
committed
Martin Drechsler
committed
Martin Drechsler
committed
self._start_acquisition_loop()
self.acq_thread = threading.Thread(
target=self.cam.live_acquisition_loop
)
self.acq_thread.start()
Martin Drechsler
committed
with self._lock:
self.simple_scan_measurement_step()
Martin Drechsler
committed
def simple_scan_measurement_end(self):
Martin Drechsler
committed
self._stop_acquisition_loop()
self.cam.TriggerMode.setString('Internal')
self.measurementEndingSignal.emit()
print('exiting scan ending in worker')
Martin Drechsler
committed
def simple_scan_measurement_step(self):
try:
value = next(self.scan_array_gen)
self.ao_to_scan.AO.set_out(value)
Martin Drechsler
committed
# aca puede esperar o chequear algo, por ahora nada
Martin Drechsler
committed
self.cam.trigger()
except StopIteration:
self.simple_scan_measurement_end()
Martin Drechsler
committed
def get_scan_signal(self, ao_name):
return [ao for ao in anal_control_signal._registry if ao.name == ao_name][0]
Martin Drechsler
committed
@QtCore.pyqtSlot(float)
def save_data_from_scan_step(self, roiData):
Martin Drechsler
committed
row = [time.time(), self.ao_to_scan.AO.current_value, roiData]
self.storage.append_data_to_current_file(row)
Martin Drechsler
committed
self.simple_scan_measurement_step()
Martin Drechsler
committed
def abort_measurement(self):
self.scan_array_gen.close()
print('Measurement aborted')