def configure_device(self): self.driver.stop_scan() from circular_buffer_numpy.circular_buffer import CircularBuffer self.buffer = CircularBuffer(shape=(self.buffer_size, len(self.scan_lst)), dtype='int16') #4320000 self.buffer.packet_length = self.packet_length print(self.scan_lst, self.phys_ch_lst, self.gain_lst) self.dev.config_channels(scan_lst=self.scan_lst, phys_ch_lst=self.phys_ch_lst, gain_lst=self.gain_lst)
def __init__(self, driver): """ initialization of the instance and creation of all other instances and variables """ from circular_buffer_numpy.circular_buffer import CircularBuffer self.buffer = CircularBuffer(shape=(1000, 4)) self.dt = 1 self.running = False self.header = ['time', 'cpu', 'memory', 'battery'] self.io_push_queue = None self.io_put_queue = None self.driver = driver self.threads = {}
def init(self, serial_number, settings=1): from numpy import zeros, nan print('') print('-------------INITIALIZING NEW CAMERA-----------') import PySpin from circular_buffer_numpy.queue import Queue from circular_buffer_numpy.circular_buffer import CircularBuffer self.acquiring = False self.cam = self.find_camera(serial_number=serial_number) self.nodes = self.get_nodes() self.height = self.get_height() self.width = self.get_width() self.queue = Queue((620, self.height + 1, self.width), dtype='uint16') self.analysis_buffer = CircularBuffer(shape=(100, 20), dtype='float64') self.last_image_time_buffer = CircularBuffer(shape=(6000, 20), dtype='float64') self.last_image_time_buffer.buffer = self.last_image_time_buffer.buffer * nan self.timestamp_buffer = CircularBuffer(shape=(6000, 1), dtype='float64') self.last_image = zeros((self.height + 1, self.width), dtype='uint16') self.set_lut_enable(False) self.set_gamma_enable(False) #self.set_gamma(0.5) self.set_autoexposure('Off') self.set_autogain('Off') self.configure_transport() try: self.cam.AcquisitionStop() print("Acquisition stopped") except PySpin.SpinnakerException as ex: print("Acquisition was already stopped") print('setting pixel format Mono11Packed') self.cam.PixelFormat.SetValue(PixelFormat_Mono12p) self.set_exposure_mode('Timed') self.exposure_time = 63000 #53500 self.gain = 0 self.black_level = 15 self.background = zeros((self.height + 1, self.width)) self.background[:self.height, :] = 15 self.background_flag = True self.conf_acq_and_trigger(settings=settings)
def init(self, pump_id=None, speed=None, backlash=None, orientation=None, volume=None): """ initialize the device level code - initializes the driver - sets default valve position to 'o' - sets initial position to 0.0 - sets initial speed to input speed value Parameters ---------- pump_id: integer pump_id speed: float initial speed of the syringe pump, default is 25 backlash: float the backlash of the syringe pump. The default value is 100 orientation: string the orientation of the syringe pump valve: Y or Z volume: float the volume of the installed syringe Returns ------- Examples -------- >>> device.init(pump_id = 1, speed = 25, backlash = 100,orientation = 'Y', volume = 250) """ from threading import RLock self.lock = RLock() from circular_buffer_numpy.circular_buffer import CircularBuffer self.buffers = {} self.buffers['position'] = CircularBuffer(shape=(1 * 3600 * 2, 2), dtype='float64') from syringe_pump.driver import Driver self.pump_id = pump_id self.driver = Driver() self.name = 'NIH_syringe_pump_' + str(pump_id) self.prefix = 'NIH:SYRINGE' + str(pump_id) if pump_id is not None: self.driver.init(pump_id, speed=speed, backlash=backlash, orientation=orientation, volume=volume) self.speed = speed self.cmd_position = 0.0 self.set_valve(b'o') self.set_speed(speed)
def read_dict(filename): from ubcs_auxiliary.save_load_object import load_from_file return load_from_file(filename) def func(i, flow, ratio): flow = flow ratio = ratio buffer.buffer.fill(0) buffer.reset() inject(pumpa=p3, pumpf=p1, tau=0.0, flow=flow, ratio=ratio, N=7, t=60) plot_2(buffer, 60, bck, comments=f'exp {i} flow {flow} ratio {ratio}') from circular_buffer_numpy.circular_buffer import CircularBuffer buffer = CircularBuffer(shape=(100, 3, 1360, 120)) def load_buffer(filename): from ubcs_auxiliary.save_load_object import load_from_file data = load_from_file(filename) if __name__ == '__main__': from tempfile import gettempdir import logging logging.basicConfig(filename=gettempdir() + '/scripts.log', level=logging.DEBUG, format="%(asctime)s %(levelname)s: %(message)s") from sys import platform if platform == "linux" or platform == "linux2":
from circular_buffer_numpy import __version__ from circular_buffer_numpy.circular_buffer import CircularBuffer from numpy import random, asarray, where, savetxt from matplotlib import pyplot as plt import timeit print('circular buffer numpy version: {}'.format(__version__)) data_dim = 1000 buffer = CircularBuffer(shape=(1000000, data_dim)) data = random.randint(2**16, size=(1000, data_dim)) def write(): global buffer buffer.append(data) def read(): global buffer data = buffer.get_last_N(N) return data header = ['N', 'data_dim', 'number', 'write time', 'read time'] number_lst = [1000000, 100000, 10000, 1000, 100] N_lst = [1, 10, 100, 1000, 10000] data_dim_lst = [10, 100, 1000] t_lst = [] for data_dim in data_dim_lst: buffer = CircularBuffer(shape=(1000000, data_dim))
class Device(object): def __init__(self, driver): """ initialization of the instance and creation of all other instances and variables """ from circular_buffer_numpy.circular_buffer import CircularBuffer self.buffer = CircularBuffer(shape=(1000, 4)) self.dt = 1 self.running = False self.header = ['time', 'cpu', 'memory', 'battery'] self.io_push_queue = None self.io_put_queue = None self.driver = driver self.threads = {} def run_once(self): """ the single execution of a code that later is looped in while running=true loop """ # arr = self.driver.read() self.buffer.append(arr) #push to IO for publishing io_dict = {} io_dict['TIME'] = arr[0, 0] io_dict['CPU'] = arr[0, 1] io_dict['MEMORY'] = arr[0, 2] io_dict['BATTERY'] = arr[0, 3] io_dict['LIST'] = [arr[0, 0], arr[0, 1], arr[0, 2], arr[0, 3]] self.io_push(io_dict) def run(self): """ while running = True loop that executes run_once() in a loop on a timer. """ from time import sleep, time self.running = True while self.running: t1 = time() self.run_once() t2 = time() dt = t2 - t1 sleep(self.dt - dt) def start(self): """ start the while running=True loop(function run()) in a separate thread. """ from ubcs_auxiliary.multithreading import new_thread self.threads['running'] = new_thread(self.run) def stop(self): """ stop the while running=True loop(function run()) in a separate thread. """ self.running = False def set_dt(self, value): """ wrapper to set dT """ self.dt = value def get_dt(self): """ wrapper to get dT """ return self.dt def io_push(self, io_dict=None): """ wrapper to push the updates into CA server for further publishing on the network. """ if self.io_push_queue is not None: self.io_push_queue.put(io_dict)
def init(self, serial_number, settings=1): from numpy import zeros, nan, ones info('') info('-------------INITIALIZING NEW CAMERA-----------') import PySpin from circular_buffer_numpy.queue import Queue self.cam = self.find_camera(serial_number=serial_number) for i in range(2): try: self.cam.BeginAcquisition() info("Acquisition Started") except PySpin.SpinnakerException as ex: info("Acquisition was already started") try: self.cam.AcquisitionStop() info("Acquisition ended") except PySpin.SpinnakerException as ex: info("Acquisition was already ended") self.nodes = self.get_nodes() #Transport Configuration self.configure_transport() #Configure Image Format self.configure_image() #Analog Configuration self.conf_acq_and_trigger(settings=settings) self.height = self.get_height() self.width = self.get_width() if (self.pixel_format == 'mono12p'): from lcp_video.analysis import get_mono12p_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12p_conversion_mask(self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif (self.pixel_format == 'mono12packed'): from lcp_video.analysis import get_mono12packed_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12packed_conversion_mask( self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif self.pixel_format == 'mono16' or self.pixel_format == 'mono12p_16': self.img_len = int(self.height * self.width) self.images_dtype = 'int16' self.queue = Queue( (self.queue_length, self.img_len + self.header_length), dtype=self.images_dtype) self.queue_frameID = Queue((self.queue_length, 2), dtype='float64') self.last_raw_image = zeros((self.img_len + self.header_length, ), dtype=self.images_dtype) from circular_buffer_numpy.circular_buffer import CircularBuffer self.hits_buffer = CircularBuffer((1350000, 2), dtype='float64') #Algorithms Configuration self.lut_enable = False self.gamma_enable = False self.autoexposure = 'Off' self.autogain = 'Off' try: self.cam.AcquisitionStop() info("Acquisition stopped") except PySpin.SpinnakerException as ex: info("Acquisition was already stopped") self.set_exposure_mode('Timed') self.exposure_time = 63000 #53500 self.gain = 0 self.black_level = 15 self.image_threshold = zeros((self.height, self.width)) + 7 self.image_median = zeros((self.height, self.width)) self.image_median[:, :] = 15 self.image_mean = zeros((self.height, self.width)) self.image_mean[:, :] = 15 self.image_mean_flag = True self.image_std = ones((self.height, self.width)) self.image_std[:, :] = 0.8 self.image_std_flag = True self.sigma_level = 6 self.mask = zeros((self.height, self.width), dtype='bool') self.mask_flag = True self.last_frameID = -1 self.num_of_missed_frames = 0
class FlirCamera(): def __init__(self, name=None, system=None): """ """ from numpy import zeros, nan self.name = name self.system = system #Acquisition self.queue_length = 32 self.acquiring = False self.header_length = 4096 #Recording self.recording_filename = f'camera_{name}.hdf5' self.recording_root = '/mnt/ramdisk/' self.recording_N = 1 self.recording = False self.recording_pointer = 0 self.recording_chunk_pointer = 0 self.recording_chunk_maxpointer = 65535 self.write_to_hdf5_benchmark = [] self.threads = {} #configuration Parameters self.nice = 0 self.reverseX = 0 self.reverseY = 0 self.rotate = 0 self.trigger = 'Software' self.calc_on_the_fly = False def init(self, serial_number, settings=1): from numpy import zeros, nan, ones info('') info('-------------INITIALIZING NEW CAMERA-----------') import PySpin from circular_buffer_numpy.queue import Queue self.cam = self.find_camera(serial_number=serial_number) for i in range(2): try: self.cam.BeginAcquisition() info("Acquisition Started") except PySpin.SpinnakerException as ex: info("Acquisition was already started") try: self.cam.AcquisitionStop() info("Acquisition ended") except PySpin.SpinnakerException as ex: info("Acquisition was already ended") self.nodes = self.get_nodes() #Transport Configuration self.configure_transport() #Configure Image Format self.configure_image() #Analog Configuration self.conf_acq_and_trigger(settings=settings) self.height = self.get_height() self.width = self.get_width() if (self.pixel_format == 'mono12p'): from lcp_video.analysis import get_mono12p_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12p_conversion_mask(self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif (self.pixel_format == 'mono12packed'): from lcp_video.analysis import get_mono12packed_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12packed_conversion_mask( self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif self.pixel_format == 'mono16' or self.pixel_format == 'mono12p_16': self.img_len = int(self.height * self.width) self.images_dtype = 'int16' self.queue = Queue( (self.queue_length, self.img_len + self.header_length), dtype=self.images_dtype) self.queue_frameID = Queue((self.queue_length, 2), dtype='float64') self.last_raw_image = zeros((self.img_len + self.header_length, ), dtype=self.images_dtype) from circular_buffer_numpy.circular_buffer import CircularBuffer self.hits_buffer = CircularBuffer((1350000, 2), dtype='float64') #Algorithms Configuration self.lut_enable = False self.gamma_enable = False self.autoexposure = 'Off' self.autogain = 'Off' try: self.cam.AcquisitionStop() info("Acquisition stopped") except PySpin.SpinnakerException as ex: info("Acquisition was already stopped") self.set_exposure_mode('Timed') self.exposure_time = 63000 #53500 self.gain = 0 self.black_level = 15 self.image_threshold = zeros((self.height, self.width)) + 7 self.image_median = zeros((self.height, self.width)) self.image_median[:, :] = 15 self.image_mean = zeros((self.height, self.width)) self.image_mean[:, :] = 15 self.image_mean_flag = True self.image_std = ones((self.height, self.width)) self.image_std[:, :] = 0.8 self.image_std_flag = True self.sigma_level = 6 self.mask = zeros((self.height, self.width), dtype='bool') self.mask_flag = True self.last_frameID = -1 self.num_of_missed_frames = 0 def read_current_setting(self): """ """ string = '' exposure_time = camera.cam.ExposureTime.GetValue() print(f'exposure time, us = {round(exposure_time,0)}') # Timed TriggerWidth exposure_mode = self.cam.ExposureMode.GetCurrentEntry().GetSymbolic() print(f'exposure mode = {exposure_mode}') resulting_frame_rate = camera.cam.AcquisitionResultingFrameRate.GetValue( ) trigger_source = camera.cam.TriggerSource.GetCurrentEntry( ).GetSymbolic() print(f'trigger selector = {trigger_source}') trigger_selector = camera.cam.TriggerSelector.GetCurrentEntry( ).GetSymbolic() print(f'trigger selector = {trigger_selector}') trigger_activation = camera.cam.TriggerActivation.GetCurrentEntry( ).GetSymbolic() print(f'trigger activation = {trigger_activation}') acquisition_frame_rate_enable = camera.cam.AcquisitionFrameRateEnable.GetValue( ) print( f'acquisition frame rate enable = {acquisition_frame_rate_enable}') acquisition_frame_rate = camera.cam.AcquisitionFrameRate.GetValue() print(f'acquisition frame rate = {acquisition_frame_rate}') x_offset = self.cam.OffsetX.GetValue() y_offset = self.cam.OffsetY.GetValue() print(f'Offset (x,y) = ({x_offset},{y_offset})') width = self.cam.Width.GetValue() height = self.cam.Height.GetValue() print(f'frame (width,height) = ({width},{height})') pixel_format = self.cam.PixelFormat.GetCurrentEntry().GetSymbolic() print(f'pixel format = {pixel_format}') def close(sself): pass def kill(self): """ """ self.pause_acquisition() sleep(1) self.stop_acquisition() sleep(0.1) del self.cam self.system.ReleaseInstance() del self def reset_to_factory_settings(self): self.pause_acquisition() self.stop_acquisition() try: self.cam.AcquisitionStop() print("Acquisition stopped") except PySpin.SpinnakerException as ex: info("Acquisition was already stopped") self.cam.UserSetSelector.SetValue(PySpin.UserSetSelector_Default) self.cam.UserSetLoad() def configure_transport(self): cam = self.cam # Configure Transport Layer Properties cam.TLStream.StreamBufferHandlingMode.SetValue( PySpin.StreamBufferHandlingMode_OldestFirst) cam.TLStream.StreamBufferCountMode.SetValue( PySpin.StreamBufferCountMode_Manual) cam.TLStream.StreamBufferCountManual.SetValue(20) info( f"Buffer Handling Mode: {cam.TLStream.StreamBufferHandlingMode.GetCurrentEntry().GetSymbolic()}" ) info( f"Buffer Count Mode: {cam.TLStream.StreamBufferCountMode.GetCurrentEntry().GetSymbolic()}" ) info( f"Buffer Count: {cam.TLStream.StreamBufferCountManual.GetValue()}") info( f"Max Buffer Count: {cam.TLStream.StreamBufferCountManual.GetMax()}" ) def deinit(self): self.stop_acquisition() self.cam.DeInit() def find_camera(self, serial_number=None): """ looks for all cameras connected and returns cam object """ cam = None cam_list = self.system.GetCameras() num_cameras = cam_list.GetSize() info(f'found {num_cameras} cameras') for i, cam in enumerate(cam_list): sn = cam.TLDevice.DeviceSerialNumber.GetValue() info(f'sn = {sn}') if serial_number == sn: self.serial_number = sn break cam_list.Clear() return cam def get_all_cameras(self): cam_list = self.system.GetCameras() num_cameras = cam_list.GetSize() info(f'found {num_cameras} cameras') cameras = [] for i, cam in enumerate(cam_list): sn = cam.TLDevice.DeviceSerialNumber.GetValue() info(f'sn = {sn}') cameras.append(sn) cam_list.Clear() return cameras def get_nodes(self): import PySpin self.cam.Init() # Retrieve GenICam nodemap nodemap = self.cam.GetNodeMap() self.nodemap = nodemap nodes = {} nodes['auto_gain'] = PySpin.CEnumerationPtr( nodemap.GetNode('GainAuto')) nodes['pixel_format'] = PySpin.CEnumerationPtr( nodemap.GetNode('PixelFormat')) nodes['gain'] = PySpin.CEnumerationPtr(nodemap.GetNode('Gain')) nodes['acquisition_mode'] = PySpin.CEnumerationPtr( nodemap.GetNode('AcquisitionMode')) nodes['exposure_time'] = PySpin.CEnumerationPtr( nodemap.GetNode('ExposureTime')) return nodes def get_image_background(self, N=0): """ function that acquires N images and calculates M1, M2 and threshold images. """ from time import ctime, time, sleep import os from numpy import sqrt from lcp_video.procedures.procedures import stats_from_chunk, find_pathnames # Load or compute stats for first chunk in dataset. info(f'starting acquiring background image file') camera.recording_stop() old_recording_chunk_maxpointer = self.recording_chunk_maxpointer self.recording_chunk_maxpointer = 2 sleep(1) string = ctime().replace(' ', '-').replace(':', '-') self.recording_init(N_frames=256, name=f'background-{string}', overwrite=True) self.queue.reset() self.recording_start() filename = self.recording_basefilename + '_0.raw.hdf5' while not os.path.exists(filename): sleep(1) camera.recording_stop() os.remove(self.recording_basefilename + '_1.tmpraw.hdf5') self.recording_chunk_maxpointer = old_recording_chunk_maxpointer # analysing raw file and creating .stats. and returning root = camera.recording_root terms = [self.recording_basefilename, '.raw.hdf5'] median, mean, var, threshold = stats_from_chunk( find_pathnames(root, terms)[0]) self.image_mean = mean self.image_std = sqrt(var) self.image_var = var self.image_median = median self.image_threshold = threshold info(f'starting acquiring background image file') def get_image_background_old(self, N=0): """ function that acquires N images and calculates M1, M2 and threshold images. """ from numpy import mean, var, copy, zeros, std, sqrt if N == 0: N = camera.queue.length raw = copy(self.queue.peek_last_N(N)) img = zeros((N, self.height, self.width)) for i in range(N): img[i] = self.convert_raw_to_image(raw[i]) self.image_mean = mean(img, axis=0) self.image_std = sqrt(var(img, axis=0) + 0.5) def get_image(self): from lcp_video.analysis import mono12p_to_image self.last_raw_image *= 0 if self.acquiring: image_result = self.cam.GetNextImage() timestamp = image_result.GetTimeStamp() frameid = image_result.GetFrameID() info(f'get : {timestamp}, {frameid}') if (self.last_frameID != -1) and ( (frameid - self.last_frameID) != 1): missed = frameid - self.last_frameID self.num_of_missed_frames += missed info( f'missed {missed} frames. {self.queue.global_rear}. Current frame ID {frameid}, last frame ID {self.last_frameID} ' ) self.last_frameID = frameid # Getting the image data as a numpy array image_res = image_result.GetData() if self.pixel_format == 'mono12p_16': image_data = mono12p_to_image(image_res, self.height, self.width) else: image_data = image_res image_result.Release() else: info('No Data in get image') image_data = zeros((self.height * self.width, )) pointer = self.img_len self.last_raw_image[:pointer] = image_data self.last_raw_image[pointer:pointer + 64] = self.get_image_header( value=int(time() * 1000000), length=64) self.last_raw_image[pointer + 64:pointer + 128] = self.get_image_header(value=timestamp, length=64) self.last_raw_image[pointer + 128:pointer + 192] = self.get_image_header(value=frameid, length=64) return self.last_raw_image def get_image_header(self, value=None, length=4096): from time import time from numpy import zeros from ubcs_auxiliary.numerical import bin_array arr = zeros((1, length)) if value is None: t = int(time() * 1000000) else: t = value arr[0, :64] = bin_array(t, 64) return arr def bin_array(num, m): from numpy import uint8, binary_repr, array """Convert a positive integer num into an m-bit bit vector""" return array(list(binary_repr(num).zfill(m))).astype(uint8) def run_once(self): from time import time from numpy import zeros, array from lcp_video.analysis import mono12p_to_image if self.acquiring: raw = self.get_image().reshape(1, self.img_len + 4096) self.queue.enqueue(raw) if not self.recording and self.calc_on_the_fly: self.last_reshaped_image = mono12p_to_image( raw[0, :self.img_len], self.height, self.width).reshape( (self.height, self.width)) hits = ((self.last_reshaped_image > (self.image_threshold + self.image_median)) * ~self.mask).sum() arr = zeros((1, 2)) arr[0, 0] = time() arr[0, 1] = hits from EPICS_CA.CAServer import casput casput(f'{self.name.upper()}_CAMERA:HITS.RBV', hits) self.hits_buffer.append(arr) def run(self): while self.acquiring: self.run_once() def start_thread(self): from ubcs_auxiliary.multithreading import new_thread if not self.acquiring: self.start_acquisition() self.threads['acquisition'] = new_thread(self.run) def stop_thread(self): if self.acquiring: self.stop_acquisition() def resume_acquisition(self): """ """ from ubcs_auxiliary.multithreading import new_thread if not self.acquiring: self.acquiring = True self.threads['acquisition'] = new_thread(self.run) def pause_acquisition(self): """ """ self.acquiring = False def start_acquisition(self): """ a wrapper to start acquisition of images. """ self.acquiring = True self.cam.BeginAcquisition() def stop_acquisition(self): """ a wrapper to stop acquisition of images. """ self.acquiring = False try: self.cam.EndAcquisition() print("Acquisition ended") except PySpin.SpinnakerException as ex: info("Acquisition was already ended") def io_put(self): pass def io_get(self): pass def get_black_level(self): import traceback from numpy import nan all = nan analog = nan digital = nan try: self.cam.BlackLevelSelector.SetValue(0) except: error( f'The self.cam.BlackLevelSelector.SetValue(0) failed {traceback.format_exc()}' ) try: all = self.cam.BlackLevel.GetValue() * 4095 / 100 except: error( f'self.cam.BlackLevel.GetValue()*4095/100 failed {traceback.format_exc()}' ) try: self.cam.BlackLevelSelector.SetValue(1) analog = self.cam.BlackLevel.GetValue() * 4095 / 100 except: error( f'sself.cam.BlackLevelSelector.SetValue(1); analog = self.cam.BlackLevel.GetValue()*4095/100 failed {traceback.format_exc()}' ) try: self.cam.BlackLevelSelector.SetValue(2) digital = self.cam.BlackLevel.GetValue() * 4095 / 100 except: error( f'self.cam.BlackLevelSelector.SetValue(2); digital = self.cam.BlackLevel.GetValue()*4095/100 failed {traceback.format_exc()}' ) try: self.cam.BlackLevelSelector.SetValue(0) except: error( f'self.cam.BlackLevelSelector.SetValue(0) failed {traceback.format_exc()}' ) return {'all': all, 'analog': analog, 'digital': digital} def set_black_level(self, value): """ """ try: self.cam.BlackLevelSelector.SetValue(0) self.cam.BlackLevel.SetValue(value * 100 / 4095) except: error( f'self.cam.BlackLevelSelector.SetValue(0); self.cam.BlackLevel.SetValue(value*100/4095) failed {traceback.format_exc()}' ) black_level = property(get_black_level, set_black_level) def get_temperature(self): """ """ temp = self.cam.DeviceTemperature.GetValue() return temp temperature = property(get_temperature) def get_fps(): return nan def set_fps(value): pass fps = property(get_fps, set_fps) def get_gain(self): return self.cam.Gain.GetValue() def set_gain(self, value): if value >= self.cam.Gain.GetMax(): value = self.cam.Gain.GetMax() elif value < self.cam.Gain.GetMin(): value = self.cam.Gain.GetMin() self.cam.Gain.SetValue(value) gain = property(get_gain, set_gain) def get_autogain(self): if self.cam is not None: value = self.cam.GainAuto.GetValue() if value == 0: return 'Off' elif value == 1: return 'Once' elif value == 2: return 'Continuous' else: return None def set_autogain(self, value): node = self.nodes['auto_gain'] off = node.GetEntryByName("Off") once = node.GetEntryByName("Once") continuous = node.GetEntryByName("Continuous") if value == 'Off': node.SetIntValue(off.GetValue()) elif value == 'Once': node.SetIntValue(once.GetValue()) elif value == 'Continuous': node.SetIntValue(continuous.GetValue()) autogain = property(get_autogain, set_autogain) def get_serial_number(self): import PySpin device_serial_number = cam.TLDevice.DeviceSerialNumber.GetValue() return device_serial_number def get_acquisition_mode(self): node = self.nodes['acquisition_mode'] def set_acquisition_mode(self, value): node = self.nodes['acquisition_mode'] continious = node.GetEntryByName("Continuous") single_frame = node.GetEntryByName("SingleFrame") multi_frame = node.GetEntryByName("MultiFrame") if value == 'Continuous': mode = continious elif value == 'SingleFrame': mode = single_frame elif value == 'MultiFrame': mode = multi_frame info(f'setting acquisition mode {value}') self.stop_acquisition() node.SetIntValue(mode) self.start_acquisition() def get_lut_enable(self): """ """ if self.cam is not None: result = self.cam.lut_enable.GetValue() else: result = None return result def set_lut_enable(self, value): """ """ if self.cam is not None: info('setting Look Up Table Enable to False') self.cam.LUTEnable.SetValue(value) lut_enable = property(get_lut_enable, set_lut_enable) def get_gamma_enable(self): """ """ if self.cam is not None: result = self.cam.GammaEnable.GetValue() else: result = None return result def set_gamma_enable(self, value): """ """ if self.cam is not None: self.cam.GammaEnable.SetValue(value) info(f'setting gamma enable {value}') gamma_enable = property(get_gamma_enable, set_gamma_enable) def get_gamma(self): if self.cam is not None: result = None #result = self.cam.Gamma.GetValue() else: result = None return result def set_gamma(self, value): """ """ if self.cam is not None: result = None #self.cam.Gamma.SetValue(value) info(f'setting gamma {value}') gamma = property(get_gamma, set_gamma) def get_height(self): if self.cam is not None: reply = self.cam.Height.GetValue() else: reply = nan return reply def get_width(self): if self.cam is not None: reply = self.cam.Width.GetValue() else: reply = nan return reply def set_exposure_mode(self, mode=None): from PySpin import ExposureMode_Timed, ExposureMode_TriggerWidth info(f'Setting up ExposureMode to {mode}') if self.cam is not None: if mode == "Timed": self.cam.ExposureMode.SetValue(ExposureMode_Timed) elif mode == "TriggerWidth": self.cam.ExposureMode.SetValue(ExposureMode_TriggerWidth) def set_autoexposure(self, value='Off'): from PySpin import ExposureAuto_Off, ExposureAuto_Continuous, ExposureAuto_Once if value == 'Off': self.cam.ExposureAuto.SetValue(ExposureAuto_Off) elif value == 'Once': self.cam.ExposureAuto.SetValue(ExposureAuto_Once) elif value == 'Continuous': self.cam.ExposureAuto.SetValue(ExposureAuto_Continuous) info(f'setting gamma enable {value}') def get_autoexposure(self): value = self.cam.ExposureAuto.GetValue() if value == 0: return 'Off' elif value == 1: return 'Once' elif value == 2: return 'Continuous' else: return 'unknown' autoexposure = property(get_autoexposure, set_autoexposure) def set_exposure_time(self, value): if self.cam is not None: self.cam.ExposureTime.SetValue(value) self._exposure_time = value else: pass def get_exposure_time(self, ): if self.cam is not None: try: return self.cam.ExposureTime.GetValue() except: return -1 else: return nan self._exposure_time = value exposure_time = property(get_exposure_time, set_exposure_time) def trigger_now(self): """ software trigger for camera """ self.cam.TriggerSoftware() def configure_image(self): import PySpin "Two different pixel formats: PixelFormat_Mono12p and PixelFormat_Mono12Packed" if self.reverseX == 1: print('reversing X axis') self.cam.ReverseX.SetValue(True, True) else: self.cam.ReverseX.SetValue(False, True) if self.reverseY == 1: print('reversing Y axis') self.cam.ReverseY.SetValue(True, True) else: self.cam.ReverseY.SetValue(False, True) info(f'setting pixel format {self.pixel_format}') if self.pixel_format == 'mono12p' or self.pixel_format == 'mono12p_16': try: self.cam.PixelFormat.SetValue(PySpin.PixelFormat_Mono12p) except: print( 'cannot set PixelFormat.SetValue(PySpin.PixelFormat_Mono12p)' ) elif self.pixel_format == 'mono12packed': try: self.cam.PixelFormat.SetValue(PySpin.PixelFormat_Mono12Packed) except: print( 'cannot set PixelFormat.SetValue(PySpin.PixelFormat_Mono12Packed)' ) elif self.pixel_format == 'mono16': try: self.cam.PixelFormat.SetValue(PySpin.PixelFormat_Mono16) except: print( 'cannot set PixelFormat.SetValue(PySpin.PixelFormat_Mono16)' ) width_max = self.cam.WidthMax.GetValue() height_max = self.cam.HeightMax.GetValue() old_offset_x = self.cam.OffsetX.GetValue() old_offset_y = self.cam.OffsetY.GetValue() new_offset_x = self.ROI_offset_x new_offset_y = self.ROI_offset_y old_width = self.cam.Width.GetValue() old_height = self.cam.Height.GetValue() new_height = self.ROI_height new_width = self.ROI_width try: if new_offset_x <= old_offset_x: info(f'setting ROI_offset_x: {self.ROI_offset_x}') self.cam.OffsetX.SetValue(self.ROI_offset_x) info(f'setting ROI_width: {self.ROI_width}') self.cam.Width.SetValue(self.ROI_width) else: info(f'setting ROI_width: {self.ROI_width}') self.cam.Width.SetValue(self.ROI_width) info(f'setting ROI_offset_x: {self.ROI_offset_x}') self.cam.OffsetX.SetValue(self.ROI_offset_x) if new_offset_y <= old_offset_y: info(f'setting ROI_offset_x: {self.ROI_offset_y}') self.cam.OffsetY.SetValue(self.ROI_offset_y) info(f'setting ROI_width: {self.ROI_width}') self.cam.Height.SetValue(self.ROI_height) else: info(f'setting ROI_width: {self.ROI_width}') self.cam.Width.SetValue(self.ROI_width) info(f'setting ROI_offset_x: {self.ROI_offset_x}') self.cam.OffsetX.SetValue(self.ROI_offset_x) info(f'setting ROI_offset_x: {self.ROI_offset_x}') self.cam.OffsetX.SetValue(self.ROI_offset_x) info(f'setting ROI_width: {self.ROI_width}') self.cam.Width.SetValue(self.ROI_width) info(f'setting ROI_height: {self.ROI_height}') self.cam.Height.SetValue(self.ROI_height) info(f'setting ROI_offset_y: {self.ROI_offset_y}') self.cam.OffsetY.SetValue(self.ROI_offset_y) except: pass def conf_acq_and_trigger(self, settings=1): """ a collection of setting defined as appropriate for the selected modes of operation. settings 1 designed for external trigger mode of operation Acquisition Mode = Continuous Acquisition FrameRate Enable = False TriggerSource = Line 0 TriggerMode = On TriggerSelector = FrameStart """ if self.cam is not None: if settings == 1: info('Acquisition and Trigger Settings: 1') info('setting continuous acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_Continuous) info('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) if self.trigger == 'Line0': info('setting TriggerSource Line0') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Line0) info('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_On) info('setting TriggerSelector FrameStart') self.cam.TriggerSelector.SetValue( PySpin.TriggerSelector_FrameStart) info('setting TriggerActivation RisingEdge') self.cam.TriggerActivation.SetValue( PySpin.TriggerActivation_RisingEdge) info('setting TriggerOverlap ReadOnly ') self.cam.TriggerOverlap.SetValue( PySpin.TriggerOverlap_ReadOut) elif self.trigger == "Software": info('setting TriggerSource Software') self.cam.TriggerSource.SetValue( PySpin.TriggerSource_Software) info('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) else: info('setting TriggerSource Software') self.cam.TriggerSource.SetValue( PySpin.TriggerSource_Software) info('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) elif settings == 2: info('Acquisition and Trigger Settings: 2') info('setting SingleFrame acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_SingleFrame) info('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) info('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) info('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) elif settings == 3: info('Acquisition and Trigger Settings: 3 (software)') info('setting continuous acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_Continuous) info('setting frame rate enable to True') self.cam.AcquisitionFrameRateEnable.SetValue(True) info('setting frame rate to 1') self.cam.AcquisitionFrameRate.SetValue(20.0) info('setting TriggerMode Off') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) info('setting TriggerSource Line0') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Line0) info('setting TriggerSource Software') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Software) def convert_raw_to_image(self, rawdata): """ """ from lcp_video.analysis import mono12p_to_image, mono12packed_to_image from numpy import right_shift rawdata = rawdata[:self.img_len] print(f'rawdata = {rawdata.dtype}') if self.pixel_format == 'mono12p': image = mono12p_to_image(rawdata=rawdata, height=self.height, width=self.width) elif self.pixel_format == 'mono12packed': mask = self.conversion_mask mask8 = self.conversion_mask8 image = mono12packe_to_image(rawdata=rawdata, height=self.height, width=self.width, mask=mask, mask8=mask8) elif self.pixel_format == 'mono16': image = right_shift(rawdata, 4).reshape((self.height, self.width)) elif self.pixel_format == 'mono12p_16': image = rawdata.reshape((self.height, self.width)) return image # Recording def recording_init(self, N_frames=1200, name='', overwrite=False): """ Initializes recording """ self.recording_basefilename = self.recording_root + f'{self.name}_{name}' self.recording_chunk_pointer = 0 filename = self.recording_basefilename + '_' + str( self.recording_chunk_pointer) + '.tmpraw.hdf5' self.recording_create_file(filename=filename, N_frames=N_frames, overwrite=overwrite) self.recording_Nframes = N_frames self.recording_pointer = 0 def recording_create_file(self, filename, N_frames, overwrite=False): """ creates hdf5 file on a drive prior to recording """ from os.path import exists from h5py import File from time import time, sleep, ctime from numpy import zeros file_action = 'a' if exists(filename): if overwrite: info( f'The HDF5 file exists but will be overwritten. The HDF5 was created. The file name is {filename}' ) file_action = 'w' else: info(f' ----WARNING----') info( f' The HDF5 file exists. Please delete it first! or use parameter overwrite = True to force deletion and creating of new file.' ) else: info(f': The HDF5 was created. The file name is {filename}') with File(filename, file_action) as f: f.create_dataset('pixel format', data=self.pixel_format) f.create_dataset('exposure time', data=self.exposure_time) f.create_dataset('black level all', data=self.black_level['all']) f.create_dataset('black level analog', data=self.black_level['analog']) f.create_dataset('black level digital', data=self.black_level['digital']) f.create_dataset('image width', data=self.width) f.create_dataset('image height', data=self.height) f.create_dataset('image offset x', data=self.ROI_offset_x) f.create_dataset('image offset y', data=self.ROI_offset_y) f.create_dataset('gain', data=self.gain) f.create_dataset('time', data=ctime(time())) f.create_dataset('temperature', data=self.temperature) f.create_dataset('images', (N_frames, self.img_len), dtype=self.images_dtype, chunks=(1, self.img_len)) f.create_dataset('timestamps_lab', (N_frames, ), dtype='float64') f.create_dataset('timestamps_camera', (N_frames, ), dtype='float64') f.create_dataset('frameIDs', (N_frames, ), dtype='int64') self.recording_filename = filename def record_dataset(self, root='/mnt/data/', name='test', N_frames=256, overwrite=False): self.recording_stop() sleep(1) self.queue.reset() self.recording_root = root self.recording_init(N_frames, name, overwrite) self.recording_start() print( f'avaiting trigger pulses. The name of the first chunk is {camera.recording_filename}' ) def record_once(self, filename, N): """ records a sequence of N frames and save them in filename hdf5 file. """ from h5py import File from time import time N = 1 #temporary work around. extract only 1 frame and save it. Got rid of for loop and now reading -1 index instead of 0. raws = self.queue.dequeue(N) if raws.shape[0] > 0: with File(filename, 'a') as f: #for i in range(N): pointer = self.recording_pointer raw = raws[-1] #raw = raws[i] tlab, tcam, frameID = self.extract_timestamp_image(raw) f['images'][pointer] = raw[:self.img_len] f['timestamps_lab'][pointer] = tlab f['timestamps_camera'][pointer] = tcam f['frameIDs'][pointer] = frameID self.recording_pointer += 1 else: warn( f'{self.name}: got empty array from deque with rear value in the queue of {self.queue.rear}' ) def recording_run(self): """ records iamges to file in a loop. """ from time import time, ctime from os import utime, rename from h5py import File while (self.recording): if self.recording_pointer == self.recording_Nframes: #create new file self.recording_chunk_pointer += 1 if self.recording_chunk_pointer >= self.recording_chunk_maxpointer: self.recording = False break self.recording_pointer = 0 rename( self.recording_basefilename + '_' + str(self.recording_chunk_pointer - 1) + '.tmpraw.hdf5', self.recording_basefilename + '_' + str(self.recording_chunk_pointer - 1) + '.raw.hdf5') f = File( self.recording_basefilename + '_' + str(self.recording_chunk_pointer - 1) + '.raw.hdf5', 'r') timestamp = f['timestamps_lab'][0] utime( self.recording_basefilename + '_' + str(self.recording_chunk_pointer - 1) + '.raw.hdf5', (timestamp, timestamp)) filename = self.recording_basefilename + '_' + str( self.recording_chunk_pointer) + '.tmpraw.hdf5' Nframes = self.recording_Nframes self.recording_create_file(filename, Nframes) filename = self.recording_filename N = self.recording_N if (self.queue.length > N): self.record_once(filename=filename, N=N) else: sleep((N + 3) * 0.051) self.recording = False info(f'Recording Loop is finished') def recording_start(self): """ a simple wrapper to start a recording_run loop in a separate thread. stops recording threads if such are active. resets queue to insure we save only new data. """ from ubcs_auxiliary.multithreading import new_thread from time import time, sleep if self.recording: self.recording_stop() sleep(1) self.queue.reset() self.recording = True self.threads['recording'] = new_thread(self.recording_run) def recording_stop(self): """ a wrapper that stops the recording loop """ self.recording = False self.threads['recording'] = None def extract_timestamp_image(self, raw): """ Extracts header information from the returns timestamp_lab,timestamp_cam,frameid """ pointer = self.img_len header_img = raw[pointer:pointer + 64] timestamp_lab = self.binarr_to_number(header_img) / 1000000 header_img = raw[pointer + 64:pointer + 128] timestamp_cam = self.binarr_to_number(header_img) header_img = raw[pointer + 128:pointer + 192] frameid = self.binarr_to_number(header_img) return timestamp_lab, timestamp_cam, frameid def binarr_to_number(self, vector): """ converts a vector of bits into an integer. """ num = 0 from numpy import flip vector = flip(vector) length = vector.shape[0] for i in range(length): num += (2**(i)) * vector[i] return num def bin_array(self, num, m): """ Converts a positive integer num into an m-bit bit vector """ from numpy import uint8, binary_repr, array return array(list(binary_repr(num).zfill(m))).astype(uint8)
"%(asctime)-15s|PID:%(process)-6s|%(levelname)-8s|%(name)s| module:%(module)s-%(funcName)s|message:%(message)s" ) print("Circular buffer library") print("two classes: server and client") print("server = server() \nclient = client()") print("---------------------------") print("Server functions") print("server.append(data)") print("server.get_all()") print("server.get_N(N = integer)") print("---------------------------") from circular_buffer_numpy.circular_buffer import CircularBuffer from numpy import random buffer = CircularBuffer(shape=(100, 2, 4), packet_length=5) buffer.reset() j = 0 for i in range(101): data = random.randint(1024, size=(5, 2, 4)) * 0 + i buffer.append(data) print(data.mean() == i) j = i % 5 print('c normal', buffer.circular_pointer, (i % 20 + 1) * 5 - 1) print('l normal', buffer.linear_pointer, (i + 1) * 5 - 1) print('c packet', buffer.circular_packet_pointer, i % 20) print('l packet', buffer.linear_packet_pointer, i) print('01234567', buffer.get_packet_circular_i_j(i % 20, i % 20).mean() == i) print('01234567', buffer.get_packet_linear_i_j(i, i).mean(), i) if i > 20:
class FlirCamera(): def __init__(self, name=None, system=None): from numpy import zeros, nan self.name = name self.system = system self.last_image_time = zeros((1, 20)) self.recording_filename = f'camera_{name}.hdf5' self.recording_root = '/mnt/data/' self.recording_N = 1 self.recording = False self.recording_pointer = 0 self.threads = {} def init(self, serial_number, settings=1): from numpy import zeros, nan print('') print('-------------INITIALIZING NEW CAMERA-----------') import PySpin from circular_buffer_numpy.queue import Queue from circular_buffer_numpy.circular_buffer import CircularBuffer self.acquiring = False self.cam = self.find_camera(serial_number=serial_number) self.nodes = self.get_nodes() self.height = self.get_height() self.width = self.get_width() self.queue = Queue((620, self.height + 1, self.width), dtype='uint16') self.analysis_buffer = CircularBuffer(shape=(100, 20), dtype='float64') self.last_image_time_buffer = CircularBuffer(shape=(6000, 20), dtype='float64') self.last_image_time_buffer.buffer = self.last_image_time_buffer.buffer * nan self.timestamp_buffer = CircularBuffer(shape=(6000, 1), dtype='float64') self.last_image = zeros((self.height + 1, self.width), dtype='uint16') self.set_lut_enable(False) self.set_gamma_enable(False) #self.set_gamma(0.5) self.set_autoexposure('Off') self.set_autogain('Off') self.configure_transport() try: self.cam.AcquisitionStop() print("Acquisition stopped") except PySpin.SpinnakerException as ex: print("Acquisition was already stopped") print('setting pixel format Mono11Packed') self.cam.PixelFormat.SetValue(PixelFormat_Mono12p) self.set_exposure_mode('Timed') self.exposure_time = 63000 #53500 self.gain = 0 self.black_level = 15 self.background = zeros((self.height + 1, self.width)) self.background[:self.height, :] = 15 self.background_flag = True self.conf_acq_and_trigger(settings=settings) def close(sself): pass def kill(self): """ """ self.pause_acquisition() sleep(1) self.stop_acquisition() sleep(0.1) del self.cam self.system.ReleaseInstance() del self def reset_to_factory_settings(self): self.pause_acquisition() self.stop_acquisition() try: self.cam.AcquisitionStop() print("Acquisition stopped") except PySpin.SpinnakerException as ex: print("Acquisition was already stopped") self.cam.UserSetSelector.SetValue(PySpin.UserSetSelector_Default) self.cam.UserSetLoad() def configure_transport(self): cam = self.cam # Configure Transport Layer Properties cam.TLStream.StreamBufferHandlingMode.SetValue( PySpin.StreamBufferHandlingMode_OldestFirst) cam.TLStream.StreamBufferCountMode.SetValue( PySpin.StreamBufferCountMode_Manual) cam.TLStream.StreamBufferCountManual.SetValue(10) print( f"Buffer Handling Mode: {cam.TLStream.StreamBufferHandlingMode.GetCurrentEntry().GetSymbolic()}" ) print( f"Buffer Count Mode: {cam.TLStream.StreamBufferCountMode.GetCurrentEntry().GetSymbolic()}" ) print( f"Buffer Count: {cam.TLStream.StreamBufferCountManual.GetValue()}") print( f"Max Buffer Count: {cam.TLStream.StreamBufferCountManual.GetMax()}" ) def deinit(self): self.stop_acquisition() self.cam.DeInit() def find_camera(self, serial_number=None): """ looks for all cameras connected and returns cam object """ cam = None cam_list = self.system.GetCameras() num_cameras = cam_list.GetSize() print(f'found {num_cameras} cameras') for i, cam in enumerate(cam_list): sn = cam.TLDevice.DeviceSerialNumber.GetValue() print(f'sn = {sn}') if serial_number == sn: break cam_list.Clear() return cam def get_all_cameras(self): cam_list = self.system.GetCameras() num_cameras = cam_list.GetSize() print(f'found {num_cameras} cameras') cameras = [] for i, cam in enumerate(cam_list): sn = cam.TLDevice.DeviceSerialNumber.GetValue() print(f'sn = {sn}') cameras.append(sn) cam_list.Clear() return cameras def get_nodes(self): import PySpin self.cam.Init() # Retrieve GenICam nodemap nodemap = self.cam.GetNodeMap() self.nodemap = nodemap nodes = {} nodes['auto_gain'] = PySpin.CEnumerationPtr( nodemap.GetNode('GainAuto')) nodes['pixel_format'] = PySpin.CEnumerationPtr( nodemap.GetNode('PixelFormat')) nodes['gain'] = PySpin.CEnumerationPtr(nodemap.GetNode('Gain')) nodes['acquisition_mode'] = PySpin.CEnumerationPtr( nodemap.GetNode('AcquisitionMode')) nodes['exposure_time'] = PySpin.CEnumerationPtr( nodemap.GetNode('ExposureTime')) return nodes def get_background(self): from numpy import mean self.background = mean(self.queue.buffer, axis=0) def get_image(self): from numpy import right_shift, nan, zeros self.last_image *= 0 if self.acquiring: self.last_image_time[0, 3] = time() image_result = self.cam.GetNextImage() timestamp = image_result.GetTimeStamp() self.last_image_result = image_result self.last_image_time[0, 4] = time() # Getting the image data as a numpy array image_data = image_result.Convert(PixelFormat_Mono16).GetNDArray() image_data = right_shift(image_data, 4) self.last_image_time[0, 5] = time() image_result.Release() self.last_image_time[0, 6] = time() else: print('No Data in get image') image_data = zeros((self.height, self.width)) self.last_image_time[0, 7] = time() self.last_image[0:self.height, :] = image_data self.last_image[self.height, :64] = self.get_image_header(value=int( time() * 1000000), length=64) self.last_image[self.height, 64:128] = self.get_image_header(value=timestamp, length=64) self.last_image_time[0, 8] = time() return self.last_image def get_image_header(self, value=None, length=4096): from time import time from numpy import zeros from ubcs_auxiliary.numerical import bin_array arr = zeros((1, length)) if value is None: t = int(time() * 1000000) else: t = value arr[0, :64] = bin_array(t, 64) return arr def binarr_to_number(self, arr): num = 0 from numpy import flip arr = flip(arr) length = arr.shape[0] for i in range(length): num += (2**(i)) * arr[i] return num def bin_array(num, m): from numpy import uint8, binary_repr, array """Convert a positive integer num into an m-bit bit vector""" return array(list(binary_repr(num).zfill(m))).astype(uint8) def run_once(self): if self.acquiring: img = self.get_image() self.last_image_time[0, 9] = time() data = img.reshape(1, img.shape[0], img.shape[1]) self.last_image_time[0, 10] = time() self.queue.enqueue(data) self.last_image_time[0, 11] = time() self.last_image_time_buffer.append(self.last_image_time) self.last_image_time[0, 12] = time() def run(self): while self.acquiring: self.run_once() def start_thread(self): from ubcs_auxiliary.multithreading import new_thread if not self.acquiring: self.start_acquisition() self.threads['acquisition'] = new_thread(self.run) def stop_thread(self): if self.acquiring: self.stop_acquisition() def resume_acquisition(self): """ """ from ubcs_auxiliary.multithreading import new_thread if not self.acquiring: self.acquiring = True self.threads['acquisition'] = new_thread(self.run) def pause_acquisition(self): """ """ self.acquiring = False def start_acquisition(self): """ a wrapper to start acquisition of images. """ self.acquiring = True self.cam.BeginAcquisition() def stop_acquisition(self): """ a wrapper to stop acquisition of images. """ self.acquiring = False try: self.cam.EndAcquisition() print("Acquisition ended") except PySpin.SpinnakerException as ex: print("Acquisition was already ended") def get_black_level(self): self.cam.BlackLevelSelector.SetValue(0) all = self.cam.BlackLevel.GetValue() * 4095 / 100 self.cam.BlackLevelSelector.SetValue(1) analog = self.cam.BlackLevel.GetValue() * 4095 / 100 self.cam.BlackLevelSelector.SetValue(2) digital = self.cam.BlackLevel.GetValue() * 4095 / 100 self.cam.BlackLevelSelector.SetValue(0) return {'all': all, 'analog': analog, 'digital': digital} def set_black_level(self, value): """ """ self.cam.BlackLevelSelector.SetValue(0) self.cam.BlackLevel.SetValue(value * 100 / 4095) black_level = property(get_black_level, set_black_level) def get_temperature(self): """ """ temp = self.cam.DeviceTemperature.GetValue() return temp temperature = property(get_temperature) def get_fps(): return nan def set_fps(value): pass fps = property(get_fps, set_fps) def get_gain(self): return self.cam.Gain.GetValue() def set_gain(self, value): if value >= self.cam.Gain.GetMax(): value = self.cam.Gain.GetMax() elif value < self.cam.Gain.GetMin(): value = self.cam.Gain.GetMin() self.cam.Gain.SetValue(value) gain = property(get_gain, set_gain) def get_autogain(self): if self.cam is not None: value = self.cam.GainAuto.GetValue() if value == 0: return 'Off' elif value == 1: return 'Once' elif value == 2: return 'Continuous' else: return None def set_autogain(self, value): node = self.nodes['auto_gain'] off = node.GetEntryByName("Off") once = node.GetEntryByName("Once") continuous = node.GetEntryByName("Continuous") if value == 'Off': node.SetIntValue(off.GetValue()) elif value == 'Once': node.SetIntValue(once.GetValue()) elif value == 'Continuous': node.SetIntValue(continuous.GetValue()) autogain = property(get_autogain, set_autogain) def get_serial_number(self): import PySpin device_serial_number = PySpin.CStringPtr( self.nodemap_tldevice.GetNode('DeviceSerialNumber')) return device_serial_number def get_acquisition_mode(self): node = self.nodes['acquisition_mode'] def set_acquisition_mode(self, value): node = self.nodes['acquisition_mode'] continious = node.GetEntryByName("Continuous") single_frame = node.GetEntryByName("SingleFrame") multi_frame = node.GetEntryByName("MultiFrame") if value == 'Continuous': mode = continious elif value == 'SingleFrame': mode = single_frame elif value == 'MultiFrame': mode = multi_frame print(f'setting acquisition mode {value}') self.stop_acquisition() node.SetIntValue(mode) self.start_acquisition() def get_lut_enable(self): """ """ if self.cam is not None: result = self.cam.LUTEnable.GetValue() else: result = None return result def set_lut_enable(self, value): """ """ if self.cam is not None: self.cam.LUTEnable.SetValue(value) print(f'setting LUT enable {value}') lut_enable = property(get_lut_enable, set_lut_enable) def get_gamma_enable(self): """ """ if self.cam is not None: result = self.cam.GammaEnable.GetValue() else: result = None return result def set_gamma_enable(self, value): """ """ if self.cam is not None: self.cam.GammaEnable.SetValue(value) print(f'setting gamma enable {value}') gamma_enable = property(get_gamma_enable, set_gamma_enable) def get_gamma(self): if self.cam is not None: result = None #result = self.cam.Gamma.GetValue() else: result = None return result def set_gamma(self, value): """ """ if self.cam is not None: result = None #self.cam.Gamma.SetValue(value) print(f'setting gamma {value}') gamma = property(get_gamma, set_gamma) def get_height(self): if self.cam is not None: reply = self.cam.Height.GetValue() else: reply = nan return reply def get_width(self): if self.cam is not None: reply = self.cam.Width.GetValue() else: reply = nan return reply def set_exposure_mode(self, mode=None): from PySpin import ExposureMode_Timed, ExposureMode_TriggerWidth print(f'Setting up ExposureMode to {mode}') if self.cam is not None: if mode == "Timed": self.cam.ExposureMode.SetValue(ExposureMode_Timed) elif mode == "TriggerWidth": self.cam.ExposureMode.SetValue(ExposureMode_TriggerWidth) def set_autoexposure(self, value='Off'): from PySpin import ExposureAuto_Off, ExposureAuto_Continuous, ExposureAuto_Once if value == 'Off': self.cam.ExposureAuto.SetValue(ExposureAuto_Off) elif value == 'Once': self.cam.ExposureAuto.SetValue(ExposureAuto_Once) elif value == 'Continuous': self.cam.ExposureAuto.SetValue(ExposureAuto_Continuous) print(f'setting gamma enable {value}') def get_autoexposure(self, bool=False): value = self.cam.ExposureAuto.GetValue() if value == 0: return 'Off' elif value == 1: return 'Once' elif value == 2: return 'Continuous' else: return 'unknown' def set_exposure_time(self, value): if self.cam is not None: self.cam.ExposureTime.SetValue(value) self._exposure_time = value else: pass def get_exposure_time(self, ): if self.cam is not None: return self.cam.ExposureTime.GetValue() else: return nan self._exposure_time = value exposure_time = property(get_exposure_time, set_exposure_time) def set_pixel_format(self, value='Mono16'): self.cam.PixelFormat.SetIn ##### Acquisition Control ##### def trigger_now(self): """ software trigger for camera """ import PySpin self.cam.TriggerSoftware() def conf_acq_and_trigger(self, settings=1): """ a collection of setting defined as appropriate for the selected modes of operation. settings 1 designed for external trigger mode of operation Acquisition Mode = Continuous Acquisition FrameRate Enable = False LUTEnable = False TriggerSource = Line 0 TriggerMode = On TriggerSelector = FrameStart """ import PySpin if self.cam is not None: if settings == 1: print('Acquisition and Trigger Settings: 1') print('setting continuous acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_Continuous) print('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) print('setting Look Up Table Enable to False') self.cam.LUTEnable.SetValue(False) print('setting TriggerSource Line0') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Line0) print('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_On) print('setting TriggerSelector FrameStart') self.cam.TriggerSelector.SetValue( PySpin.TriggerSelector_FrameStart) print('setting TriggerActivation RisingEdge') self.cam.TriggerActivation.SetValue( PySpin.TriggerActivation_RisingEdge) print('setting TriggerOverlap ReadOnly ') self.cam.TriggerOverlap.SetValue(PySpin.TriggerOverlap_ReadOut) elif settings == 2: print('Acquisition and Trigger Settings: 2') print('setting SingleFrame acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_SingleFrame) print('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) print('setting Look Up Table Enable to False') self.cam.LUTEnable.SetValue(False) print('setting frame rate enable to False') self.cam.AcquisitionFrameRateEnable.SetValue(False) print('setting TriggerMode On') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) elif settings == 3: print('Acquisition and Trigger Settings: 3 (software)') print('setting continuous acquisition mode') self.cam.AcquisitionMode.SetIntValue( PySpin.AcquisitionMode_Continuous) print('setting Look Up Table Enable to False') self.cam.LUTEnable.SetValue(False) print('setting frame rate enable to True') self.cam.AcquisitionFrameRateEnable.SetValue(True) print('setting frame rate to 1') self.cam.AcquisitionFrameRate.SetValue(20.0) print('setting TriggerMode Off') self.cam.TriggerMode.SetIntValue(PySpin.TriggerMode_Off) print('setting TriggerSource Line0') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Line0) print('setting TriggerSource Software') self.cam.TriggerSource.SetValue(PySpin.TriggerSource_Software) def recording_init(self, filename=None, N_frames=1200, comments=''): from os.path import exists from h5py import File from time import time, sleep, ctime from numpy import zeros if filename is None: filename = self.recording_root + f'{self.name}_{comments}.raw.hdf5' if exists(filename): print('----WARNING----') print('The HDF5 file exists. Please delete it first!') else: print(f'The HDF5 was created. The file name is {filename}') with File(filename, 'a') as f: f.create_dataset('exposure time', data='trigger width') f.create_dataset('black level all', data=self.black_level['all']) f.create_dataset('black level analog', data=self.black_level['analog']) f.create_dataset('black level digital', data=self.black_level['digital']) f.create_dataset('gain', data=self.gain) f.create_dataset('time', data=ctime(time())) f.create_dataset('temperature', data=self.temperature) f.create_dataset('images', (N_frames, self.height, self.width), dtype='int16', chunks=(1, self.height, self.width)) f.create_dataset('timestamps_lab', (N_frames, ), dtype='float64') f.create_dataset('timestamps_camera', (N_frames, ), dtype='float64') self.recording_filename = filename self.recording_N_frames = N_frames self.recording_pointer = 0 self.recording_buffer = zeros( (self.recording_N, self.height, self.width)) def record_once(self, filename, N): from h5py import File from numpy import copy, array self.recording_buffer = self.queue.dequeue(N) images = self.recording_buffer if images.shape[0] > 0: with File(filename, 'a') as f: for i in range(N): pointer = self.recording_pointer image = images[i] tlab, tcam = self.extract_timestamp_image(image) f['images'][pointer] = image[:self.height, :] f['timestamps_lab'][pointer] = tlab f['timestamps_camera'][pointer] = tcam self.recording_pointer += 1 else: print( f'{self.name}: got empty array from deque with rear value in the queue of {self.queue.rear}' ) def recording_run(self): from h5py import File from time import time, ctime filename = self.recording_filename while (self.recording) and (self.recording_pointer < self.recording_N_frames): N = self.recording_N if self.queue.length > N: self.record_once(filename=filename, N=N) else: sleep((N + 3) * 0.051) self.recording = False print(ctime(time()), f'Recording of {self.recording_N_frames} is Finished') def recording_chunk_run(self, M): from h5py import File filename = self.recording_filename i = 0 while (i < M) and self.recording: N = self.recording_N if self.queue.length > N: self.record_once(filename=filename, N=N) i += N else: sleep((N + 3) * self._exposure_time / 1000000) self.recording = False print(f'{self.recording_filename}: recording stopped') def recording_start(self): from ubcs_auxiliary.multithreading import new_thread self.recording = True new_thread(self.recording_run) def recording_stop(self): self.recording = False def recording_scratch(self): root = self.recording_root + 'scratch/' def full_speed(): filename = self.recording_filename if images.shape[0] > 0: for i in range(N): if self.recording_pointer >= self.recording_N_frames: self.recording = False break print( 'Recording of {self.recording_N_frames} is Finished' ) pointer = self.recording_pointer image = images[i] with File(filename, 'a') as f: f['images'][pointer] = image[:self.height, :] tlab, tcam = self.extract_timestamp_image(image) f['timestamps_lab'][pointer] = tlab f['timestamps_camera'][pointer] = tcam #f['frameID'][pointer] = tcam self.recording_pointer += 1 def extract_timestamp_image(self, arr): """ Takes array of images (length, rows, cols) and returns the header data The header information is located in the last row (row = 3000) of an image """ header_arr = arr[-1, :64] timestamp_lab = self.binarr_to_number(header_arr) / 1000000 header_arr = arr[-1, 64:128] timestamp_cam = self.binarr_to_number(header_arr) return timestamp_lab, timestamp_cam def binarr_to_number(self, vector): num = 0 from numpy import flip vector = flip(vector) length = vector.shape[0] for i in range(length): num += (2**(i)) * vector[i] return num def bin_array(self, num, m): from numpy import uint8, binary_repr, array """Convert a positive integer num into an m-bit bit vector""" return array(list(binary_repr(num).zfill(m))).astype(uint8)
def init(self, config_filename): from numpy import zeros, nan, ones info('') info('-------------INITIALIZING NEW CAMERA-----------') import PySpin from circular_buffer_numpy.queue import Queue config, flag = self.read_config_file(config_filename) self.pixel_format = config['pixel_format'] self.ROI_width = int(config['ROI_width']) self.ROI_height = int(config['ROI_height']) self.ROI_offset_x = int(config['ROI_offset_x']) self.ROI_offset_y = int(config['ROI_offset_y']) self.reverseX = int(config['ROI_offset_y']) self.reverseY = int(config['ROI_offset_y']) self.rotate = int(config['rotate']) self.trigger = config['trigger'] if 'binning_selector' in config.keys(): self.binning_selector = config['binning_selector'] if 'binning_horizontal_mode' in config.keys(): self.binning_horizontal_mode = config['binning_horizontal_mode'] if 'binning_vertical_mode' in config.keys(): self.binning_vertical_mode = config['binning_vertical_mode'] if 'binning_vertical' in config.keys(): self.binning_vertical = int(config['binning_vertical']) if 'binning_horizontal' in config.keys(): self.binning_horizontal = int(config['binning_horizontal']) nice = int(config['nice']) self.nice = nice info(f'setting up nice {nice}') if nice != 0: os.nice(nice) sn = str(config['serial_number']) self.init(serial_number=sn) self.start_thread() self.set_exposure_time(config['exposure_time']) self.cam = self.find_camera(serial_number=serial_number) for i in range(2): try: self.cam.AcquisitionStart() info("Acquisition Started") except PySpin.SpinnakerException as ex: info("Acquisition was already started") try: self.cam.AcquisitionStop() info("Acquisition ended") except PySpin.SpinnakerException as ex: info("Acquisition was already ended") # reset camera to default settings self.nodes = self.get_nodes() #Transport Configuration self.configure_transport() #Configure Image Format self.configure_image() #Analog Configuration self.conf_acq_and_trigger(settings=settings) self.height = self.get_height() self.width = self.get_width() if (self.pixel_format == 'mono8'): from lcp_video.analysis import get_mono12p_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width) self.images_dtype = 'uint8' self.conversion_mask = get_mono12p_conversion_mask(self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif (self.pixel_format == 'mono12p'): from lcp_video.analysis import get_mono12p_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12p_conversion_mask(self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif (self.pixel_format == 'mono12packed'): from lcp_video.analysis import get_mono12packed_conversion_mask, get_mono12p_conversion_mask_8bit self.img_len = int(self.height * self.width * 1.5) self.images_dtype = 'uint8' self.conversion_mask = get_mono12packed_conversion_mask( self.img_len) self.conversion_mask8 = get_mono12p_conversion_mask_8bit( self.img_len) elif self.pixel_format == 'mono16' or self.pixel_format == 'mono12p_16': self.img_len = int(self.height * self.width) self.images_dtype = 'int16' self.queue = Queue( (self.queue_length, self.img_len + self.header_length), dtype=self.images_dtype) self.queue_frameID = Queue((self.queue_length, 2), dtype='float64') self.last_raw_image = zeros((self.img_len + self.header_length, ), dtype=self.images_dtype) from circular_buffer_numpy.circular_buffer import CircularBuffer self.hits_buffer = CircularBuffer((1350000, 2), dtype='float64') #Algorithms Configuration self.lut_enable = False self.gamma_enable = False self.autoexposure = 'Off' self.autogain = 'Off' try: self.cam.AcquisitionStop() info("Acquisition stopped") except PySpin.SpinnakerException as ex: info("Acquisition was already stopped") self.set_exposure_mode('Timed') self.exposure_time = 63000 #53500 self.gain = 0 self.black_level = 15 self.image_threshold = zeros((self.height, self.width)) + 7 self.image_median = zeros((self.height, self.width)) self.image_median[:, :] = 15 self.image_mean = zeros((self.height, self.width)) self.image_mean[:, :] = 15 self.image_mean_flag = True self.image_std = ones((self.height, self.width)) self.image_std[:, :] = 0.8 self.image_std_flag = True self.sigma_level = 6 self.mask = zeros((self.height, self.width), dtype='bool') self.mask_flag = True self.last_frameID = -1 self.num_of_missed_frames = 0
class Device(object): db = DataBase(root='TEMP', name='dataq_covid19') name = SavedProperty(db, 'name', 'dataq_covid19').init() prefix = SavedProperty(db, 'prefix', 'NIH:DI245').init() scan_lst = SavedProperty(db, 'scan_lst', ['0', '1', '2', '3']).init() phys_ch_lst = SavedProperty(db, 'phys_ch_lst', ['0', '1', '2', '3']).init() gain_lst = SavedProperty(db, 'gain_lst', ['5', '5', '5', '5']).init() buffer_size = SavedProperty(db, 'buffer_size', 4320000).init() packet_length = SavedProperty(db, 'packet_length', 10).init() calib = SavedProperty(db, 'calib', [0.559, 2.7, 3.2, -1.2, 0]).init() time_out = SavedProperty(db, 'time_out', 0).init() cjc_value = SavedProperty(db, 'cjc_value', '').init() SN = SavedProperty(db, 'SN', '').init() def __init__(self, name=None): if name is not None: self.name = name else: self.name = 'DI245_noname' self.recording_flag = False def init(self, serial_number): self.dev = Driver() self.driver = self.dev success = self.driver.init(serial_number) if success: self.configure_device() debug('DI245 is found: %r' % self.driver.available_ports) self.info_dict = {} self.info_dict['scan_lst'] = self.scan_lst self.info_dict['phys_ch_lst'] = self.phys_ch_lst self.info_dict['gain_lst'] = self.gain_lst self.info_dict['RingBuffer_size'] = self.buffer_size self.info_dict['calib'] = self.calib self.info_dict['time_out'] = self.time_out self.info_dict['cjc_value'] = self.cjc_value self.info_dict['SN'] = self.SN reply = True else: reply = False error('DI-245 is not found') return reply def stop(self): self.full_stop() def configure_device(self): self.driver.stop_scan() from circular_buffer_numpy.circular_buffer import CircularBuffer self.buffer = CircularBuffer(shape=(self.buffer_size, len(self.scan_lst)), dtype='int16') #4320000 self.buffer.packet_length = self.packet_length print(self.scan_lst, self.phys_ch_lst, self.gain_lst) self.dev.config_channels(scan_lst=self.scan_lst, phys_ch_lst=self.phys_ch_lst, gain_lst=self.gain_lst) def run_once(self): """ """ from tempfile import gettempdir from numpy import mean from time import time root = gettempdir() length = self.packet_length if self.driver.waiting[0] > length * 4 * 2: value_array = self.dev.read_number( N_of_channels=len(self.scan_lst), N_of_points=length).T - 8192 self.buffer.append(value_array) T_top = mean(value_array[:, 2]) * 0.036621 + 100 T_bottom = mean(value_array[:, 3]) * 0.036621 + 100 Vs = mean(value_array[:, 0] * 10.0 / (2**13)) Vo = mean(value_array[:, 1] * 5.0 / (2**13)) rh = mean(self.relative_humidity(Vs, Vo, T_top, T_bottom)) if self.recording_flag: with open(root + '/covid19_DI245.txt', "a") as f: string = f'{time()},{round(T_top,2)}, {round(T_bottom,2)}, {round(rh,2)}, {round(Vs,2)},{round(Vo,2)} \n' f.write(string) from EPICS_CA.CAServer import casput casput('BigBox:TEMP_TOP', T_top) casput('BigBox:TEMP_BOTTOM', T_bottom) casput('BigBox:RH', rh) else: sleep(0.01) def run(self): while self.running: self.run_once() self.running = False def start(self, new_thread=True): from ubcs_auxiliary.threading import new_thread as thread from time import time self.driver.start_scan() self.time_start = self._time_start = time() self.running = True if new_thread: thread(self.run) else: self.run() def stop(self): from time import sleep self.running = False sleep(1) self.driver.stop_scan() def full_stop(self): try: self.dev.full_stop() self.running = False except: warn('dev is not initialized') def save_to_a_file(self): debug('save to a file pressed %r' % time()) pass def run_full(self, serial_number=''): self.init(serial_number=serial_number) self.start() def start_recording(): self.recording_flag = True def stop_recording(): self.recording_flag = False def relative_humidity(self, Vs, Vo, T1, T2): return 149.09 * ((Vo / Vs) - 0.1515) / (1 - 0.002048 * (0.5 * (T1 + T2)))