remove more coding cookies

mainly from frappy_psi

Change-Id: I192811459aebe97f3076888cd31a308a51e6aa49
This commit is contained in:
zolliker 2024-01-29 14:14:09 +01:00
parent 75cfffb548
commit d55ee42612
28 changed files with 396 additions and 438 deletions

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,294 +1,293 @@
# -*- coding: utf-8 -*- """
""" Created on Tue Nov 26 15:42:43 2019
Created on Tue Nov 26 15:42:43 2019
@author: tartarotti_d-adm
@author: tartarotti_d-adm """
"""
import numpy as np
import numpy as np import ctypes as ct
import ctypes as ct import time
import time from numpy import sqrt, arctan2, sin, cos
from numpy import sqrt, arctan2, sin, cos
#from pylab import *
#from pylab import *
from scipy import signal
from scipy import signal
#ADQAPI = ct.cdll.LoadLibrary("ADQAPI.dll")
#ADQAPI = ct.cdll.LoadLibrary("ADQAPI.dll") ADQAPI = ct.cdll.LoadLibrary("libadq.so.0")
ADQAPI = ct.cdll.LoadLibrary("libadq.so.0")
#For different trigger modes
#For different trigger modes SW_TRIG = 1
SW_TRIG = 1 EXT_TRIG_1 = 2 #This external trigger does not work if the level of the trigger is very close to 0.5V. Now we have it close to 3V, and it works
EXT_TRIG_1 = 2 #This external trigger does not work if the level of the trigger is very close to 0.5V. Now we have it close to 3V, and it works EXT_TRIG_2 = 7
EXT_TRIG_2 = 7 EXT_TRIG_3 = 8
EXT_TRIG_3 = 8 LVL_TRIG = 3
LVL_TRIG = 3 INT_TRIG = 4
INT_TRIG = 4 LVL_FALLING = 0
LVL_FALLING = 0 LVL_RISING = 1
LVL_RISING = 1
#samples_per_record=16384
#samples_per_record=16384 ADQ_TRANSFER_MODE_NORMAL = 0x00
ADQ_TRANSFER_MODE_NORMAL = 0x00 ADQ_CHANNELS_MASK = 0x3
ADQ_CHANNELS_MASK = 0x3
#f_LO = 40
#f_LO = 40
def butter_lowpass(cutoff, sr, order=5):
def butter_lowpass(cutoff, sr, order=5): nyq = 0.5 * sr
nyq = 0.5 * sr normal_cutoff = cutoff / nyq
normal_cutoff = cutoff / nyq b, a = signal.butter(order, normal_cutoff, btype = 'low', analog = False)
b, a = signal.butter(order, normal_cutoff, btype = 'low', analog = False) return b, a
return b, a
class Adq(object):
class Adq(object): max_number_of_channels = 2
max_number_of_channels = 2 samp_freq = 2
samp_freq = 2 #ndecimate = 50 # decimation ratio (2GHz / 40 MHz)
#ndecimate = 50 # decimation ratio (2GHz / 40 MHz) ndecimate = 50
ndecimate = 50
def __init__(self, number_of_records, samples_per_record, bw_cutoff):
def __init__(self, number_of_records, samples_per_record, bw_cutoff): self.number_of_records = number_of_records
self.number_of_records = number_of_records self.samples_per_record = samples_per_record
self.samples_per_record = samples_per_record self.bw_cutoff = bw_cutoff
self.bw_cutoff = bw_cutoff ADQAPI.ADQAPI_GetRevision()
ADQAPI.ADQAPI_GetRevision()
# Manually set return type from some ADQAPI functions
# Manually set return type from some ADQAPI functions ADQAPI.CreateADQControlUnit.restype = ct.c_void_p
ADQAPI.CreateADQControlUnit.restype = ct.c_void_p ADQAPI.ADQ_GetRevision.restype = ct.c_void_p
ADQAPI.ADQ_GetRevision.restype = ct.c_void_p ADQAPI.ADQ_GetPtrStream.restype = ct.POINTER(ct.c_int16)
ADQAPI.ADQ_GetPtrStream.restype = ct.POINTER(ct.c_int16) ADQAPI.ADQControlUnit_FindDevices.argtypes = [ct.c_void_p]
ADQAPI.ADQControlUnit_FindDevices.argtypes = [ct.c_void_p] # Create ADQControlUnit
# Create ADQControlUnit self.adq_cu = ct.c_void_p(ADQAPI.CreateADQControlUnit())
self.adq_cu = ct.c_void_p(ADQAPI.CreateADQControlUnit()) ADQAPI.ADQControlUnit_EnableErrorTrace(self.adq_cu, 3, '.')
ADQAPI.ADQControlUnit_EnableErrorTrace(self.adq_cu, 3, '.') self.adq_num = 1
self.adq_num = 1
# Find ADQ devices
# Find ADQ devices ADQAPI.ADQControlUnit_FindDevices(self.adq_cu)
ADQAPI.ADQControlUnit_FindDevices(self.adq_cu) n_of_ADQ = ADQAPI.ADQControlUnit_NofADQ(self.adq_cu)
n_of_ADQ = ADQAPI.ADQControlUnit_NofADQ(self.adq_cu) if n_of_ADQ != 1:
if n_of_ADQ != 1: raise ValueError('number of ADQs must be 1, not %d' % n_of_ADQ)
raise ValueError('number of ADQs must be 1, not %d' % n_of_ADQ)
rev = ADQAPI.ADQ_GetRevision(self.adq_cu, self.adq_num)
rev = ADQAPI.ADQ_GetRevision(self.adq_cu, self.adq_num) revision = ct.cast(rev,ct.POINTER(ct.c_int))
revision = ct.cast(rev,ct.POINTER(ct.c_int)) print('\nConnected to ADQ #1')
print('\nConnected to ADQ #1') # Print revision information
# Print revision information print('FPGA Revision: {}'.format(revision[0]))
print('FPGA Revision: {}'.format(revision[0])) if (revision[1]):
if (revision[1]): print('Local copy')
print('Local copy') else :
else : print('SVN Managed')
print('SVN Managed') if (revision[2]):
if (revision[2]): print('Mixed Revision')
print('Mixed Revision') else :
else : print('SVN Updated')
print('SVN Updated') print('')
print('')
ADQ_CLOCK_INT_INTREF = 0 #internal clock source
ADQ_CLOCK_INT_INTREF = 0 #internal clock source ADQ_CLOCK_EXT_REF = 1 #internal clock source, external reference
ADQ_CLOCK_EXT_REF = 1 #internal clock source, external reference ADQ_CLOCK_EXT_CLOCK = 2 #External clock source
ADQ_CLOCK_EXT_CLOCK = 2 #External clock source ADQAPI.ADQ_SetClockSource(self.adq_cu, self.adq_num, ADQ_CLOCK_EXT_REF);
ADQAPI.ADQ_SetClockSource(self.adq_cu, self.adq_num, ADQ_CLOCK_EXT_REF);
##########################
########################## # Test pattern
# Test pattern #ADQAPI.ADQ_SetTestPatternMode(self.adq_cu, self.adq_num, 4)
#ADQAPI.ADQ_SetTestPatternMode(self.adq_cu, self.adq_num, 4) ##########################
########################## # Sample skip
# Sample skip #ADQAPI.ADQ_SetSampleSkip(self.adq_cu, self.adq_num, 1)
#ADQAPI.ADQ_SetSampleSkip(self.adq_cu, self.adq_num, 1) ##########################
##########################
# Set trig mode
# Set trig mode self.trigger = EXT_TRIG_1
self.trigger = EXT_TRIG_1 #trigger = LVL_TRIG
#trigger = LVL_TRIG success = ADQAPI.ADQ_SetTriggerMode(self.adq_cu, self.adq_num, self.trigger)
success = ADQAPI.ADQ_SetTriggerMode(self.adq_cu, self.adq_num, self.trigger) if (success == 0):
if (success == 0): print('ADQ_SetTriggerMode failed.')
print('ADQ_SetTriggerMode failed.') if (self.trigger == LVL_TRIG):
if (self.trigger == LVL_TRIG): success = ADQAPI.ADQ_SetLvlTrigLevel(self.adq_cu, self.adq_num, -100)
success = ADQAPI.ADQ_SetLvlTrigLevel(self.adq_cu, self.adq_num, -100) if (success == 0):
if (success == 0): print('ADQ_SetLvlTrigLevel failed.')
print('ADQ_SetLvlTrigLevel failed.') success = ADQAPI.ADQ_SetTrigLevelResetValue(self.adq_cu, self.adq_num, 1000)
success = ADQAPI.ADQ_SetTrigLevelResetValue(self.adq_cu, self.adq_num, 1000) if (success == 0):
if (success == 0): print('ADQ_SetTrigLevelResetValue failed.')
print('ADQ_SetTrigLevelResetValue failed.') success = ADQAPI.ADQ_SetLvlTrigChannel(self.adq_cu, self.adq_num, 1)
success = ADQAPI.ADQ_SetLvlTrigChannel(self.adq_cu, self.adq_num, 1) if (success == 0):
if (success == 0): print('ADQ_SetLvlTrigChannel failed.')
print('ADQ_SetLvlTrigChannel failed.') success = ADQAPI.ADQ_SetLvlTrigEdge(self.adq_cu, self.adq_num, LVL_RISING)
success = ADQAPI.ADQ_SetLvlTrigEdge(self.adq_cu, self.adq_num, LVL_RISING) if (success == 0):
if (success == 0): print('ADQ_SetLvlTrigEdge failed.')
print('ADQ_SetLvlTrigEdge failed.') elif (self.trigger == EXT_TRIG_1) :
elif (self.trigger == EXT_TRIG_1) : success = ADQAPI.ADQ_SetExternTrigEdge(self.adq_cu, self.adq_num,2)
success = ADQAPI.ADQ_SetExternTrigEdge(self.adq_cu, self.adq_num,2) if (success == 0):
if (success == 0): print('ADQ_SetLvlTrigEdge failed.')
print('ADQ_SetLvlTrigEdge failed.') # success = ADQAPI.ADQ_SetTriggerThresholdVoltage(self.adq_cu, self.adq_num, trigger, ct.c_double(0.2))
# success = ADQAPI.ADQ_SetTriggerThresholdVoltage(self.adq_cu, self.adq_num, trigger, ct.c_double(0.2)) # if (success == 0):
# if (success == 0): # print('SetTriggerThresholdVoltage failed.')
# print('SetTriggerThresholdVoltage failed.') print("CHANNEL:"+str(ct.c_int(ADQAPI.ADQ_GetLvlTrigChannel(self.adq_cu, self.adq_num))))
print("CHANNEL:"+str(ct.c_int(ADQAPI.ADQ_GetLvlTrigChannel(self.adq_cu, self.adq_num)))) self.setup_target_buffers()
self.setup_target_buffers()
def setup_target_buffers(self):
def setup_target_buffers(self): # Setup target buffers for data
# Setup target buffers for data self.target_buffers=(ct.POINTER(ct.c_int16 * self.samples_per_record * self.number_of_records)
self.target_buffers=(ct.POINTER(ct.c_int16 * self.samples_per_record * self.number_of_records) * self.max_number_of_channels)()
* self.max_number_of_channels)() for bufp in self.target_buffers:
for bufp in self.target_buffers: bufp.contents = (ct.c_int16 * self.samples_per_record * self.number_of_records)()
bufp.contents = (ct.c_int16 * self.samples_per_record * self.number_of_records)()
def deletecu(self):
def deletecu(self): # Only disarm trigger after data is collected
# Only disarm trigger after data is collected ADQAPI.ADQ_DisarmTrigger(self.adq_cu, self.adq_num)
ADQAPI.ADQ_DisarmTrigger(self.adq_cu, self.adq_num) ADQAPI.ADQ_MultiRecordClose(self.adq_cu, self.adq_num);
ADQAPI.ADQ_MultiRecordClose(self.adq_cu, self.adq_num); # Delete ADQControlunit
# Delete ADQControlunit ADQAPI.DeleteADQControlUnit(self.adq_cu)
ADQAPI.DeleteADQControlUnit(self.adq_cu)
def start(self):
def start(self): """start datat acquisition"""
"""start datat acquisition""" # samples_per_records = samples_per_record/number_of_records
# samples_per_records = samples_per_record/number_of_records # Change number of pulses to be acquired acording to how many records are taken
# Change number of pulses to be acquired acording to how many records are taken # Start acquisition
# Start acquisition ADQAPI.ADQ_MultiRecordSetup(self.adq_cu, self.adq_num,
ADQAPI.ADQ_MultiRecordSetup(self.adq_cu, self.adq_num, self.number_of_records,
self.number_of_records, self.samples_per_record)
self.samples_per_record)
ADQAPI.ADQ_DisarmTrigger(self.adq_cu, self.adq_num)
ADQAPI.ADQ_DisarmTrigger(self.adq_cu, self.adq_num) ADQAPI.ADQ_ArmTrigger(self.adq_cu, self.adq_num)
ADQAPI.ADQ_ArmTrigger(self.adq_cu, self.adq_num)
def getdata(self):
def getdata(self): """wait for aquisition to be finished and get data"""
"""wait for aquisition to be finished and get data""" #start = time.time()
#start = time.time() while(ADQAPI.ADQ_GetAcquiredAll(self.adq_cu,self.adq_num) == 0):
while(ADQAPI.ADQ_GetAcquiredAll(self.adq_cu,self.adq_num) == 0): time.sleep(0.001)
time.sleep(0.001) #if (self.trigger == SW_TRIG):
#if (self.trigger == SW_TRIG): # ADQAPI.ADQ_SWTrig(self.adq_cu, self.adq_num)
# ADQAPI.ADQ_SWTrig(self.adq_cu, self.adq_num) #mid = time.time()
#mid = time.time() status = ADQAPI.ADQ_GetData(self.adq_cu, self.adq_num, self.target_buffers,
status = ADQAPI.ADQ_GetData(self.adq_cu, self.adq_num, self.target_buffers, self.samples_per_record * self.number_of_records, 2,
self.samples_per_record * self.number_of_records, 2, 0, self.number_of_records, ADQ_CHANNELS_MASK,
0, self.number_of_records, ADQ_CHANNELS_MASK, 0, self.samples_per_record, ADQ_TRANSFER_MODE_NORMAL);
0, self.samples_per_record, ADQ_TRANSFER_MODE_NORMAL); #print(time.time()-mid,mid-start)
#print(time.time()-mid,mid-start) if not status:
if not status: raise ValueError('no succesS from ADQ_GetDATA')
raise ValueError('no succesS from ADQ_GetDATA') # Now this is an array with all records, but the time is artificial
# Now this is an array with all records, but the time is artificial data = []
data = [] for ch in range(2):
for ch in range(2): onedim = np.frombuffer(self.target_buffers[ch].contents, dtype=np.int16)
onedim = np.frombuffer(self.target_buffers[ch].contents, dtype=np.int16) data.append(onedim.reshape(self.number_of_records, self.samples_per_record) / float(2**14)) # 14 bits ADC
data.append(onedim.reshape(self.number_of_records, self.samples_per_record) / float(2**14)) # 14 bits ADC return data
return data
def acquire(self):
def acquire(self): self.start()
self.start() return self.getdata()
return self.getdata() '''
''' def average(self, data):
def average(self, data): #Average over records
#Average over records return [data[ch].sum(axis=0) / self.number_of_records for ch in range(2)]
return [data[ch].sum(axis=0) / self.number_of_records for ch in range(2)]
def iq(self, channel, f_LO):
def iq(self, channel, f_LO): newx = np.linspace(0, self.samples_per_record /2, self.samples_per_record)
newx = np.linspace(0, self.samples_per_record /2, self.samples_per_record) s0 = channel /((2**16)/2)*0.5*np.exp(1j*2*np.pi*f_LO/(1e3)*newx)
s0 = channel /((2**16)/2)*0.5*np.exp(1j*2*np.pi*f_LO/(1e3)*newx) I0 = s0.real
I0 = s0.real Q0 = s0.imag
Q0 = s0.imag return I0, Q0
return I0, Q0
def fitting(self, data, f_LO, ti, tf):
def fitting(self, data, f_LO, ti, tf): # As long as data[0] is the pulse
# As long as data[0] is the pulse si = 2*ti #Those are for fitting the pulse
si = 2*ti #Those are for fitting the pulse sf = 2*tf
sf = 2*tf phase = np.zeros(self.number_of_records)
phase = np.zeros(self.number_of_records) amplitude = np.zeros(self.number_of_records)
amplitude = np.zeros(self.number_of_records) offset = np.zeros(self.number_of_records)
offset = np.zeros(self.number_of_records)
for i in range(self.number_of_records):
for i in range(self.number_of_records): phase[i], amplitude[i] = sineW(data[0][i][si:sf],f_LO*1e-9,ti,tf)
phase[i], amplitude[i] = sineW(data[0][i][si:sf],f_LO*1e-9,ti,tf) offset[i] = np.average(data[0][i][si:sf])
offset[i] = np.average(data[0][i][si:sf]) return phase, amplitude, offset
return phase, amplitude, offset
def waveIQ(self, channel,ti,f_LO):
def waveIQ(self, channel,ti,f_LO): #channel is not the sample data
#channel is not the sample data t = np.linspace(0, self.samples_per_record /2, self.samples_per_record + 1)[:-1]
t = np.linspace(0, self.samples_per_record /2, self.samples_per_record + 1)[:-1] si = 2*ti # Again that is where the wave pulse starts
si = 2*ti # Again that is where the wave pulse starts cwi = np.zeros((self.number_of_records,self.samples_per_record))
cwi = np.zeros((self.number_of_records,self.samples_per_record)) cwq = np.zeros((self.number_of_records,self.samples_per_record))
cwq = np.zeros((self.number_of_records,self.samples_per_record)) iq = np.zeros((self.number_of_records,self.samples_per_record))
iq = np.zeros((self.number_of_records,self.samples_per_record)) q = np.zeros((self.number_of_records,self.samples_per_record))
q = np.zeros((self.number_of_records,self.samples_per_record)) for i in range(self.number_of_records):
for i in range(self.number_of_records): cwi[i] = np.zeros(self.samples_per_record)
cwi[i] = np.zeros(self.samples_per_record) cwq[i] = np.zeros(self.samples_per_record)
cwq[i] = np.zeros(self.samples_per_record) cwi[i] = amplitude[i]*sin(t[si:]*f_LO*1e-9*2*np.pi+phase[i]*np.pi/180)+bias[i]
cwi[i] = amplitude[i]*sin(t[si:]*f_LO*1e-9*2*np.pi+phase[i]*np.pi/180)+bias[i] cwq[i] = amplitude[i]*sin(t[si:]*f_LO*1e-9*(2*np.pi+(phase[i]+90)*np.pi/180))+bias[i]
cwq[i] = amplitude[i]*sin(t[si:]*f_LO*1e-9*(2*np.pi+(phase[i]+90)*np.pi/180))+bias[i]
iq[i] = channel[i]*cwi[i]
iq[i] = channel[i]*cwi[i] q[i] = channel[i]*cwq[i]
q[i] = channel[i]*cwq[i]
return iq,q
return iq,q '''
''' def sinW(self,sig,freq,ti,tf):
def sinW(self,sig,freq,ti,tf): # sig: signal array
# sig: signal array # freq
# freq # ti, tf: initial and end time
# ti, tf: initial and end time si = int(ti * self.samp_freq)
si = int(ti * self.samp_freq) nperiods = freq * (tf - ti)
nperiods = freq * (tf - ti) n = int(round(max(2, int(nperiods)) / nperiods * (tf-ti) * self.samp_freq))
n = int(round(max(2, int(nperiods)) / nperiods * (tf-ti) * self.samp_freq)) self.nperiods = n
self.nperiods = n t = np.arange(si, len(sig)) / self.samp_freq
t = np.arange(si, len(sig)) / self.samp_freq t = t[:n]
t = t[:n] self.pulselen = n / self.samp_freq
self.pulselen = n / self.samp_freq sig = sig[si:si+n]
sig = sig[si:si+n] a = 2*np.sum(sig*np.cos(2*np.pi*freq*t))/len(sig)
a = 2*np.sum(sig*np.cos(2*np.pi*freq*t))/len(sig) b = 2*np.sum(sig*np.sin(2*np.pi*freq*t))/len(sig)
b = 2*np.sum(sig*np.sin(2*np.pi*freq*t))/len(sig) return a, b
return a, b
def mix(self, sigin, sigout, freq, ti, tf):
def mix(self, sigin, sigout, freq, ti, tf): # sigin, sigout: signal array, incomping, output
# sigin, sigout: signal array, incomping, output # freq
# freq # ti, tf: initial and end time if sigin
# ti, tf: initial and end time if sigin a, b = self.sinW(sigin, freq, ti, tf)
a, b = self.sinW(sigin, freq, ti, tf) phase = arctan2(a,b) * 180 / np.pi
phase = arctan2(a,b) * 180 / np.pi amp = sqrt(a**2 + b**2)
amp = sqrt(a**2 + b**2) a, b = a/amp, b/amp
a, b = a/amp, b/amp #si = int(ti * self.samp_freq)
#si = int(ti * self.samp_freq) t = np.arange(len(sigout)) / self.samp_freq
t = np.arange(len(sigout)) / self.samp_freq wave1 = sigout * (a * cos(2*np.pi*freq*t) + b * sin(2*np.pi*freq*t))
wave1 = sigout * (a * cos(2*np.pi*freq*t) + b * sin(2*np.pi*freq*t)) wave2 = sigout * (a * sin(2*np.pi*freq*t) - b * cos(2*np.pi*freq*t))
wave2 = sigout * (a * sin(2*np.pi*freq*t) - b * cos(2*np.pi*freq*t)) return wave1, wave2
return wave1, wave2
def averageiq(self, data, freq, ti, tf):
def averageiq(self, data, freq, ti, tf): '''Average over records'''
'''Average over records''' iorq = np.array([self.mix(data[0][i], data[1][i], freq, ti, tf) for i in range(self.number_of_records)])
iorq = np.array([self.mix(data[0][i], data[1][i], freq, ti, tf) for i in range(self.number_of_records)]) # iorq = np.array([self.mix(data[0][:], data[1][:], freq, ti, tf)])
# iorq = np.array([self.mix(data[0][:], data[1][:], freq, ti, tf)]) return iorq.sum(axis=0) / self.number_of_records
return iorq.sum(axis=0) / self.number_of_records
def filtro(self, iorq, cutoff):
def filtro(self, iorq, cutoff): b, a = butter_lowpass(cutoff, self.samp_freq*1e9)
b, a = butter_lowpass(cutoff, self.samp_freq*1e9)
#ifi = np.array(signal.filtfilt(b,a,iorq[0]))
#ifi = np.array(signal.filtfilt(b,a,iorq[0])) #qf = np.array(signal.filtfilt(b,a,iorq[1]))
#qf = np.array(signal.filtfilt(b,a,iorq[1])) iqf = [signal.filtfilt(b,a,iorq[i]) for i in np.arange(len(iorq))]
iqf = [signal.filtfilt(b,a,iorq[i]) for i in np.arange(len(iorq))]
return iqf
return iqf
def box(self, iorq, ti, tf):
def box(self, iorq, ti, tf): si = int(self.samp_freq * ti)
si = int(self.samp_freq * ti) sf = int(self.samp_freq * tf)
sf = int(self.samp_freq * tf) bxa = [sum(iorq[i][si:sf])/(sf-si) for i in np.arange(len(iorq))]
bxa = [sum(iorq[i][si:sf])/(sf-si) for i in np.arange(len(iorq))] return bxa
return bxa
def gates_and_curves(self, data, freq, pulse, roi):
def gates_and_curves(self, data, freq, pulse, roi): """return iq values of rois and prepare plottable curves for iq"""
"""return iq values of rois and prepare plottable curves for iq""" times = []
times = [] times.append(('aviq', time.time()))
times.append(('aviq', time.time())) iq = self.averageiq(data,freq*1e-9,*pulse)
iq = self.averageiq(data,freq*1e-9,*pulse) times.append(('filtro', time.time()))
times.append(('filtro', time.time())) iqf = self.filtro(iq,self.bw_cutoff)
iqf = self.filtro(iq,self.bw_cutoff) m = len(iqf[0]) // self.ndecimate
m = len(iqf[0]) // self.ndecimate times.append(('iqdec', time.time()))
times.append(('iqdec', time.time())) iqd = np.average(np.resize(iqf, (2, m, self.ndecimate)), axis=2)
iqd = np.average(np.resize(iqf, (2, m, self.ndecimate)), axis=2) t_axis = np.arange(m) * self.ndecimate / self.samp_freq
t_axis = np.arange(m) * self.ndecimate / self.samp_freq pulsig = np.abs(data[0][0])
pulsig = np.abs(data[0][0]) times.append(('pulsig', time.time()))
times.append(('pulsig', time.time())) pulsig = np.average(np.resize(pulsig, (m, self.ndecimate)), axis=1)
pulsig = np.average(np.resize(pulsig, (m, self.ndecimate)), axis=1) self.curves = (t_axis, iqd[0], iqd[1], pulsig)
self.curves = (t_axis, iqd[0], iqd[1], pulsig) #print(times)
#print(times) return [self.box(iqf,*r) for r in roi]
return [self.box(iqf,*r) for r in roi]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,102 +1,101 @@
# -*- coding: utf-8 -*- """
""" Created on Tue Feb 4 11:07:56 2020
Created on Tue Feb 4 11:07:56 2020
@author: tartarotti_d-adm
@author: tartarotti_d-adm """
"""
import numpy as np
import numpy as np import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
def rect(x1, x2, y1, y2):
def rect(x1, x2, y1, y2): return np.array([[x1,x2,x2,x1,x1],[y1,y1,y2,y2,y1]])
return np.array([[x1,x2,x2,x1,x1],[y1,y1,y2,y2,y1]])
NAN = float('nan')
NAN = float('nan')
def rects(intervals, y12):
def rects(intervals, y12): result = [rect(*intervals[0], *y12)]
result = [rect(*intervals[0], *y12)] for x12 in intervals[1:]:
for x12 in intervals[1:]: result.append([[NAN],[NAN]])
result.append([[NAN],[NAN]]) result.append(rect(*x12, *y12))
result.append(rect(*x12, *y12)) return np.concatenate(result, axis=1)
return np.concatenate(result, axis=1)
class Plot:
class Plot: def __init__(self, maxy):
def __init__(self, maxy): self.lines = {}
self.lines = {} self.yaxis = ((-2 * maxy, maxy), (-maxy, 2 * maxy))
self.yaxis = ((-2 * maxy, maxy), (-maxy, 2 * maxy)) self.first = True
self.first = True self.fig = None
self.fig = None
def set_line(self, iax, name, data, fmt, **kwds):
def set_line(self, iax, name, data, fmt, **kwds): """
""" plot or update a line
plot or update a line
when called with self.first = True: plot the line
when called with self.first = True: plot the line when called with self.first = False: update the line
when called with self.first = False: update the line
iax: 0: left, 1: right yaxis
iax: 0: left, 1: right yaxis name: the name of the line. used also as label for legend, if not starting with underscore
name: the name of the line. used also as label for legend, if not starting with underscore data: data[0] and data[1] are used for x/y data respectively
data: data[0] and data[1] are used for x/y data respectively fmt, other keywords: forwarded to <axis>.plot
fmt, other keywords: forwarded to <axis>.plot """
""" # ax: 0: left, 1: right
# ax: 0: left, 1: right if self.first:
if self.first: if name.startswith('_'):
if name.startswith('_'): label = '_nolegend_'
label = '_nolegend_' else:
else: label = name
label = name self.lines[name], = self.ax[iax].plot(data[0], data[1], fmt, label=label, **kwds)
self.lines[name], = self.ax[iax].plot(data[0], data[1], fmt, label=label, **kwds) else:
else: self.lines[name].set_data(data[0:2])
self.lines[name].set_data(data[0:2])
def close(self):
def close(self): if self.fig:
if self.fig: plt.close(self.fig)
plt.close(self.fig) self.fig = None
self.fig = None self.first = True
self.first = True
def plot(self, curves, rois=None, average=None):
def plot(self, curves, rois=None, average=None): boxes = rects(rois[1:], self.yaxis[0])
boxes = rects(rois[1:], self.yaxis[0]) pbox = rect(*rois[0], *self.yaxis[1])
pbox = rect(*rois[0], *self.yaxis[1]) rbox = rect(*rois[1], *self.yaxis[0])
rbox = rect(*rois[1], *self.yaxis[0])
pshift = self.yaxis[0][1] * 0.5
pshift = self.yaxis[0][1] * 0.5 pulse = curves[3] - pshift
pulse = curves[3] - pshift # normalized to 0.8 * pshift:
# normalized to 0.8 * pshift: #pulse = (curves[3] / np.max(curves[3]))* pshift * 0.8 - pshift
#pulse = (curves[3] / np.max(curves[3]))* pshift * 0.8 - pshift
try:
try: if self.first:
if self.first: plt.ion()
plt.ion() self.fig, axleft = plt.subplots(figsize=(15,7))
self.fig, axleft = plt.subplots(figsize=(15,7)) plt.title("I/Q", fontsize=14)
plt.title("I/Q", fontsize=14) axleft.set_xlim(0, curves[0][-1])
axleft.set_xlim(0, curves[0][-1]) self.ax = [axleft, axleft.twinx()]
self.ax = [axleft, axleft.twinx()] self.ax[0].axhline(y=0, color='#cccccc') # show x-axis line
self.ax[0].axhline(y=0, color='#cccccc') # show x-axis line self.ax[1].axhline(y=0, color='#cccccc')
self.ax[1].axhline(y=0, color='#cccccc') self.ax[0].set_ylim(*self.yaxis[0])
self.ax[0].set_ylim(*self.yaxis[0]) self.ax[1].set_ylim(*self.yaxis[1])
self.ax[1].set_ylim(*self.yaxis[1])
self.set_line(0, "I", curves, 'b-') # using curves [0] and [1]
self.set_line(0, "I", curves, 'b-') # using curves [0] and [1] self.set_line(0, "_Iaverage", average, 'b.')
self.set_line(0, "_Iaverage", average, 'b.')
self.set_line(0, "Ampl", (curves[0],np.sqrt(curves[1]**2+curves[2]**2)), '#808080')
self.set_line(0, "Ampl", (curves[0],np.sqrt(curves[1]**2+curves[2]**2)), '#808080')
self.set_line(1, "Q", (curves[0], curves[2]), 'g-')
self.set_line(1, "Q", (curves[0], curves[2]), 'g-') self.set_line(1, "_Qaverage", (average[0], average[2]), 'g.')
self.set_line(1, "_Qaverage", (average[0], average[2]), 'g.')
self.set_line(0, "pulse", (curves[0], pulse), 'c-')
self.set_line(0, "pulse", (curves[0], pulse), 'c-')
self.set_line(0, "roi's", boxes, 'm-')
self.set_line(0, "roi's", boxes, 'm-') self.set_line(1, "pulse reg", pbox, 'k-')
self.set_line(1, "pulse reg", pbox, 'k-') self.set_line(0, "ctrl reg", rbox, 'r-')
self.set_line(0, "ctrl reg", rbox, 'r-')
if self.first:
if self.first: self.fig.legend(fontsize=12)
self.fig.legend(fontsize=12) plt.tight_layout()
plt.tight_layout() finally:
finally: self.first = False
self.first = False
plt.draw()
plt.draw() self.fig.canvas.draw()
self.fig.canvas.draw() self.fig.canvas.flush_events()
self.fig.canvas.flush_events()

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# #
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under # This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software # the terms of the GNU General Public License as published by the Free Software
@ -86,4 +85,4 @@ class Vector(Drivable, VectorRd):
self.parameters['target'].datatype = TupleOf(*members) self.parameters['target'].datatype = TupleOf(*members)
def write_target(self, value): def write_target(self, value):
return tuple((c.write_target(v) for v, c in zip(value, self.components))) return tuple((c.write_target(v) for v, c in zip(value, self.components)))

View File

@ -1,2 +1,2 @@
2024-01-29 wip develop 2024-01-29 wip develop
2023-10-01 wip mlz # test wise