sqdtoolz 0.9.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqdtoolz/Drivers/ACQ_ETH_FPGA.py +509 -0
- sqdtoolz/Drivers/ACQ_M4i_Digitiser.py +397 -0
- sqdtoolz/Drivers/ACQ_TektronixDSA70804B.py +775 -0
- sqdtoolz/Drivers/ATTEN_Vaunix.py +106 -0
- sqdtoolz/Drivers/AWG5014C.py +296 -0
- sqdtoolz/Drivers/Agilent_N8241A.py +1797 -0
- sqdtoolz/Drivers/DDG_DG645.py +232 -0
- sqdtoolz/Drivers/DSO_DS1054Z.py +426 -0
- sqdtoolz/Drivers/Dependencies/Agilent_N8241A_constants_python3.py +794 -0
- sqdtoolz/Drivers/Dependencies/PrologixGPIBEthernet.py +65 -0
- sqdtoolz/Drivers/Dependencies/RPi_gpio_interface.py +91 -0
- sqdtoolz/Drivers/Dependencies/RPi_serial_interface.py +82 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/M4i.py +1380 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/__init__.py +0 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/py_header/__init__.py +0 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/py_header/regs.py +2863 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/py_header/spcerr.py +81 -0
- sqdtoolz/Drivers/Dependencies/Spectrum/pyspcm.py +245 -0
- sqdtoolz/Drivers/Dependencies/teproteus.py +977 -0
- sqdtoolz/Drivers/Dependencies/tevisainst.py +498 -0
- sqdtoolz/Drivers/FGEN_FY6900.py +234 -0
- sqdtoolz/Drivers/MWS_SGS100A.py +203 -0
- sqdtoolz/Drivers/MWS_SMB100A.py +274 -0
- sqdtoolz/Drivers/MWS_WFSynthHDProV2.py +222 -0
- sqdtoolz/Drivers/MWS_WFSynthHDProV2_RPi.py +56 -0
- sqdtoolz/Drivers/SA_RS_FSV.py +246 -0
- sqdtoolz/Drivers/SMU_B2901A.py +226 -0
- sqdtoolz/Drivers/SMU_Keithley236.py +404 -0
- sqdtoolz/Drivers/SMU_TENMA_72_2710.py +192 -0
- sqdtoolz/Drivers/SW_BJT_RPi.py +87 -0
- sqdtoolz/Drivers/SW_BJT_RPi_Multi.py +107 -0
- sqdtoolz/Drivers/SW_FPGA_VNA.py +114 -0
- sqdtoolz/Drivers/SW_RFSwitchController_CryoRadiall.py +146 -0
- sqdtoolz/Drivers/SW_RPiCryo.py +198 -0
- sqdtoolz/Drivers/SW_RPiRadial.py +183 -0
- sqdtoolz/Drivers/SW_RpiIQBox.py +41 -0
- sqdtoolz/Drivers/THERM_TC0309.py +72 -0
- sqdtoolz/Drivers/Tabor_P2584M.py +1874 -0
- sqdtoolz/Drivers/VNA_Agilent_N5232A.py +680 -0
- sqdtoolz/Drivers/VNA_Keysight_P9373A.py +17 -0
- sqdtoolz/Drivers/VOLT_Delft_IVVI.py +1194 -0
- sqdtoolz/Drivers/VOLT_IVVI_pyro.py +135 -0
- sqdtoolz/Drivers/VOLT_RpiMultiDAC.py +74 -0
- sqdtoolz/Drivers/VOLT_SIM928_PLX.py +371 -0
- sqdtoolz/Drivers/VOLT_SIM928_VCOM.py +381 -0
- sqdtoolz/Drivers/VOLT_SIM928_pyro.py +50 -0
- sqdtoolz/Drivers/VOLT_Stahl_16CH.py +304 -0
- sqdtoolz/Drivers/ZILabOneQ.py +41 -0
- sqdtoolz/Drivers/__init__.py +0 -0
- sqdtoolz/Drivers/dummyACQ.py +109 -0
- sqdtoolz/Drivers/dummyACQex.py +120 -0
- sqdtoolz/Drivers/dummyAWG.py +121 -0
- sqdtoolz/Drivers/dummyDDG.py +116 -0
- sqdtoolz/Drivers/dummyGENmwSource.py +125 -0
- sqdtoolz/Drivers/dummySMU.py +100 -0
- sqdtoolz/Experiment.py +406 -0
- sqdtoolz/ExperimentConfiguration.py +464 -0
- sqdtoolz/ExperimentSpecification.py +150 -0
- sqdtoolz/ExperimentSpecifications/__init__.py +0 -0
- sqdtoolz/ExperimentSweeps.py +70 -0
- sqdtoolz/Experiments/Experimental/ExpACstarkRamseyGE.py +122 -0
- sqdtoolz/Experiments/Experimental/ExpBodePlot.py +69 -0
- sqdtoolz/Experiments/Experimental/ExpCalibGE.py +67 -0
- sqdtoolz/Experiments/Experimental/ExpCalibXrot.py +107 -0
- sqdtoolz/Experiments/Experimental/ExpCalibXrotAuto.py +126 -0
- sqdtoolz/Experiments/Experimental/ExpGateBenchmarks.py +109 -0
- sqdtoolz/Experiments/Experimental/ExpHahnGE.py +121 -0
- sqdtoolz/Experiments/Experimental/ExpMixerCalibrationLO.py +130 -0
- sqdtoolz/Experiments/Experimental/ExpMixerCalibrationSB.py +102 -0
- sqdtoolz/Experiments/Experimental/ExpPeakScouterIQ.py +68 -0
- sqdtoolz/Experiments/Experimental/ExpPulsedCavitySpec.py +93 -0
- sqdtoolz/Experiments/Experimental/ExpQubitFluxSweep.py +83 -0
- sqdtoolz/Experiments/Experimental/ExpRabi.py +170 -0
- sqdtoolz/Experiments/Experimental/ExpRamseyGE.py +125 -0
- sqdtoolz/Experiments/Experimental/ExpRandomisedBenchmarking.py +142 -0
- sqdtoolz/Experiments/Experimental/ExpResistanceIVs.py +54 -0
- sqdtoolz/Experiments/Experimental/ExpResistanceIVsFast.py +45 -0
- sqdtoolz/Experiments/Experimental/ExpSingleShotGE.py +74 -0
- sqdtoolz/Experiments/Experimental/ExpT1GE.py +119 -0
- sqdtoolz/Experiments/Experimental/ExpVNAEquations.py +120 -0
- sqdtoolz/Experiments/Experimental/ExpVNAoptimalSNR.py +38 -0
- sqdtoolz/Experiments/Experimental/ExpZIActiveResetTuneup.py +81 -0
- sqdtoolz/Experiments/Experimental/ExpZIBenchmarkETH.py +95 -0
- sqdtoolz/Experiments/Experimental/ExpZIBlobs.py +83 -0
- sqdtoolz/Experiments/Experimental/ExpZICalibX.py +142 -0
- sqdtoolz/Experiments/Experimental/ExpZIChevrons.py +65 -0
- sqdtoolz/Experiments/Experimental/ExpZIChevrons2QFixedCoupler.py +182 -0
- sqdtoolz/Experiments/Experimental/ExpZICryoscope.py +313 -0
- sqdtoolz/Experiments/Experimental/ExpZIDailyTuneup.py +132 -0
- sqdtoolz/Experiments/Experimental/ExpZIDispersive.py +110 -0
- sqdtoolz/Experiments/Experimental/ExpZIDragScaling.py +90 -0
- sqdtoolz/Experiments/Experimental/ExpZIFixedCouplerTuneup.py +152 -0
- sqdtoolz/Experiments/Experimental/ExpZIQASM.py +133 -0
- sqdtoolz/Experiments/Experimental/ExpZIQASMDataViewer.py +63 -0
- sqdtoolz/Experiments/Experimental/ExpZIQubitFluxSweep.py +252 -0
- sqdtoolz/Experiments/Experimental/ExpZIQubitPowerSweep.py +114 -0
- sqdtoolz/Experiments/Experimental/ExpZIQubitSpec.py +59 -0
- sqdtoolz/Experiments/Experimental/ExpZIRabi.py +111 -0
- sqdtoolz/Experiments/Experimental/ExpZIRabiRamseyT1.py +164 -0
- sqdtoolz/Experiments/Experimental/ExpZIRamsey.py +103 -0
- sqdtoolz/Experiments/Experimental/ExpZIRandomisedBenchmarking.py +126 -0
- sqdtoolz/Experiments/Experimental/ExpZIRes.py +123 -0
- sqdtoolz/Experiments/Experimental/ExpZIResFluxSweep.py +101 -0
- sqdtoolz/Experiments/Experimental/ExpZIResOptimal.py +224 -0
- sqdtoolz/Experiments/Experimental/ExpZIResPowerSweep.py +66 -0
- sqdtoolz/Experiments/Experimental/ExpZISingleQubitTuneup.py +363 -0
- sqdtoolz/Experiments/Experimental/ExpZIT1.py +86 -0
- sqdtoolz/Experiments/Experimental/ExpZIT1SingleShot.py +53 -0
- sqdtoolz/Experiments/Experimental/ExpZITWPATuneup.py +134 -0
- sqdtoolz/Experiments/Experimental/ExpZIqubit.py +289 -0
- sqdtoolz/Experiments/Experimental/ZI/calibrate_tunable_transmon_fixed_coupler.py +311 -0
- sqdtoolz/Experiments/Experimental/ZI/calibrate_tunable_transmon_fixed_coupler_osc.py +291 -0
- sqdtoolz/Experiments/Experimental/ZI/cryo_scope.py +329 -0
- sqdtoolz/Experiments/Experimental/ZI/flux_scope.py +309 -0
- sqdtoolz/Experiments/Experimental/ZI/oqasm_scheduled_qubits.py +320 -0
- sqdtoolz/Experiments/Experimental/ZI/qubit_single_chevron.py +290 -0
- sqdtoolz/Experiments/Experimental/ZI/qubit_spectroscopy_gef.py +288 -0
- sqdtoolz/Experiments/Experimental/ZI/single_qubit_gates.py +259 -0
- sqdtoolz/Experiments/Experimental/ZI/single_qubit_gates_sweep.py +280 -0
- sqdtoolz/Experiments/Experimental/ZI/sinlge_qubit_gates_sweep_chunking.py +288 -0
- sqdtoolz/HAL/ACQ.py +171 -0
- sqdtoolz/HAL/ACQdso.py +166 -0
- sqdtoolz/HAL/ACQsa.py +108 -0
- sqdtoolz/HAL/ACQvna.py +192 -0
- sqdtoolz/HAL/AWG.py +1057 -0
- sqdtoolz/HAL/DDG.py +93 -0
- sqdtoolz/HAL/DataProcessor.py +45 -0
- sqdtoolz/HAL/DecisionBlock.py +10 -0
- sqdtoolz/HAL/Decisions/DEC_SVM.py +38 -0
- sqdtoolz/HAL/GENatten.py +34 -0
- sqdtoolz/HAL/GENfuncGen.py +86 -0
- sqdtoolz/HAL/GENmwSource.py +132 -0
- sqdtoolz/HAL/GENmwSrcAWG.py +157 -0
- sqdtoolz/HAL/GENsmu.py +176 -0
- sqdtoolz/HAL/GENswitch.py +38 -0
- sqdtoolz/HAL/GENswitchTrig.py +44 -0
- sqdtoolz/HAL/GENtherm.py +29 -0
- sqdtoolz/HAL/GENvoltSource.py +50 -0
- sqdtoolz/HAL/HALbase.py +78 -0
- sqdtoolz/HAL/LockableProperties.py +22 -0
- sqdtoolz/HAL/MultiACQ.py +160 -0
- sqdtoolz/HAL/Processors/CPU/CPU_AmpPhs.py +48 -0
- sqdtoolz/HAL/Processors/CPU/CPU_ChannelArithmetic.py +72 -0
- sqdtoolz/HAL/Processors/CPU/CPU_ConstantArithmetic.py +54 -0
- sqdtoolz/HAL/Processors/CPU/CPU_DDC.py +52 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Decimation.py +47 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Duplicate.py +35 -0
- sqdtoolz/HAL/Processors/CPU/CPU_ESD.py +54 -0
- sqdtoolz/HAL/Processors/CPU/CPU_FFT.py +55 -0
- sqdtoolz/HAL/Processors/CPU/CPU_FIR.py +67 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Integrate.py +39 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Max.py +39 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Mean.py +39 -0
- sqdtoolz/HAL/Processors/CPU/CPU_MeanBlock.py +46 -0
- sqdtoolz/HAL/Processors/CPU/CPU_MeanVariance.py +43 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Rename.py +27 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Slice.py +46 -0
- sqdtoolz/HAL/Processors/CPU/CPU_Variance.py +39 -0
- sqdtoolz/HAL/Processors/CPU/CPU_kMeans.py +49 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_DDC.py +54 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_DDCFIR.py +62 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_Decimation.py +29 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_FFT.py +24 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_FIR.py +56 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_Integrate.py +27 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_Mean.py +27 -0
- sqdtoolz/HAL/Processors/FPGA/FPGA_MultiplierConst.py +47 -0
- sqdtoolz/HAL/Processors/GPU/GPU_ChannelArithmetic.py +74 -0
- sqdtoolz/HAL/Processors/GPU/GPU_ConstantArithmetic.py +54 -0
- sqdtoolz/HAL/Processors/GPU/GPU_DDC.py +52 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Decimation.py +52 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Duplicate.py +35 -0
- sqdtoolz/HAL/Processors/GPU/GPU_ESD.py +56 -0
- sqdtoolz/HAL/Processors/GPU/GPU_FFT.py +57 -0
- sqdtoolz/HAL/Processors/GPU/GPU_FIR.py +87 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Integrate.py +37 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Max.py +37 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Mean.py +37 -0
- sqdtoolz/HAL/Processors/GPU/GPU_MeanBlock.py +47 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Rename.py +27 -0
- sqdtoolz/HAL/Processors/GPU/GPU_Slice.py +37 -0
- sqdtoolz/HAL/Processors/ProcessorCPU.py +176 -0
- sqdtoolz/HAL/Processors/ProcessorFPGA.py +91 -0
- sqdtoolz/HAL/Processors/ProcessorGPU.py +197 -0
- sqdtoolz/HAL/SOFTpid.py +169 -0
- sqdtoolz/HAL/SOFTqpu.py +254 -0
- sqdtoolz/HAL/TriggerPulse.py +223 -0
- sqdtoolz/HAL/WaveformGeneric.py +49 -0
- sqdtoolz/HAL/WaveformMapper.py +11 -0
- sqdtoolz/HAL/WaveformSegments.py +601 -0
- sqdtoolz/HAL/WaveformTransformations.py +221 -0
- sqdtoolz/HAL/ZI/QuantumElements/TunableTransmonCouplerFixed.py +139 -0
- sqdtoolz/HAL/ZI/QuantumElements/__init__.py +18 -0
- sqdtoolz/HAL/ZI/ZIACQ.py +209 -0
- sqdtoolz/HAL/ZI/ZIPulses.py +253 -0
- sqdtoolz/HAL/ZI/ZIQuantumElement.py +126 -0
- sqdtoolz/HAL/ZI/ZIQubit.py +294 -0
- sqdtoolz/HAL/ZI/ZIbase.py +3 -0
- sqdtoolz/HAL/ZI/__init__.py +3 -0
- sqdtoolz/Laboratory.py +654 -0
- sqdtoolz/Utilities/DataFitting.py +776 -0
- sqdtoolz/Utilities/DataIQDiscriminate.py +160 -0
- sqdtoolz/Utilities/DataIQNormalise.py +76 -0
- sqdtoolz/Utilities/DataQubitFlux.py +309 -0
- sqdtoolz/Utilities/DataSingleShotThreshold.py +92 -0
- sqdtoolz/Utilities/ExperimentViewer.py +878 -0
- sqdtoolz/Utilities/FileConverter.py +49 -0
- sqdtoolz/Utilities/FileIO.py +592 -0
- sqdtoolz/Utilities/FileJSON.py +48 -0
- sqdtoolz/Utilities/Flattenator.py +168 -0
- sqdtoolz/Utilities/Miscellaneous.py +111 -0
- sqdtoolz/Utilities/OpenQASM/ParserOpenQASM.py +1195 -0
- sqdtoolz/Utilities/OpenQASM/ScheduleParametersJSONConfigZI.py +72 -0
- sqdtoolz/Utilities/OpenQASM/ScheduleParametersSoftQPUZI.py +44 -0
- sqdtoolz/Utilities/OpenQASM/__init__.py +27 -0
- sqdtoolz/Utilities/OpenQASM/includes/stdgates.inc +270 -0
- sqdtoolz/Utilities/OpenQASM/includes/stdgates_transmon_fixed_coupler.inc +24 -0
- sqdtoolz/Utilities/Optimisers.py +64 -0
- sqdtoolz/Utilities/QubitGates.py +264 -0
- sqdtoolz/Utilities/ResonatorTools.py +2469 -0
- sqdtoolz/Utilities/TimingPlots.py +328 -0
- sqdtoolz/Variable.py +387 -0
- sqdtoolz/__init__.py +42 -0
- sqdtoolz-0.9.0.dev1.dist-info/METADATA +125 -0
- sqdtoolz-0.9.0.dev1.dist-info/RECORD +228 -0
- sqdtoolz-0.9.0.dev1.dist-info/WHEEL +5 -0
- sqdtoolz-0.9.0.dev1.dist-info/licenses/LICENSE +203 -0
- sqdtoolz-0.9.0.dev1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from qcodes import Instrument, InstrumentChannel, VisaInstrument
|
|
3
|
+
import qcodes.utils.validators as valids
|
|
4
|
+
|
|
5
|
+
from sqdtoolz.HAL.Processors.ProcessorFPGA import ProcessorFPGA
|
|
6
|
+
from sqdtoolz.HAL.Processors.FPGA.FPGA_DDC import FPGA_DDC
|
|
7
|
+
from sqdtoolz.HAL.Processors.FPGA.FPGA_FIR import FPGA_FIR
|
|
8
|
+
from sqdtoolz.HAL.Processors.FPGA.FPGA_Decimation import FPGA_Decimation
|
|
9
|
+
from sqdtoolz.HAL.Processors.FPGA.FPGA_Mean import FPGA_Mean
|
|
10
|
+
from sqdtoolz.HAL.Processors.FPGA.FPGA_Integrate import FPGA_Integrate
|
|
11
|
+
|
|
12
|
+
import time
|
|
13
|
+
|
|
14
|
+
import Pyro4
|
|
15
|
+
|
|
16
|
+
Pyro4.config.SERIALIZER = 'serpent'
|
|
17
|
+
Pyro4.config.PICKLE_PROTOCOL_VERSION = 2
|
|
18
|
+
Pyro4.config.SERIALIZERS_ACCEPTED = set(['pickle','json', 'marshal', 'serpent'])
|
|
19
|
+
# from uqtools import Parameter
|
|
20
|
+
import pickle
|
|
21
|
+
|
|
22
|
+
class ETHFPGA(Instrument):
|
|
23
|
+
def __init__(self, name, uri, app_name='TVMODEV02', **kwargs):
|
|
24
|
+
super().__init__(name, **kwargs)
|
|
25
|
+
|
|
26
|
+
self._proxy = None
|
|
27
|
+
self._remote_name = 'fpga'
|
|
28
|
+
with open(uri, 'r') as fh:
|
|
29
|
+
self._uri = uri
|
|
30
|
+
|
|
31
|
+
self._proxy = Pyro4.Proxy(fh.read())
|
|
32
|
+
if self._remote_name not in self._proxy.get_instrument_names():
|
|
33
|
+
raise ValueError('Instrument {} not recognized by server.'.format(self._remote_name))
|
|
34
|
+
assert self._proxy != None, "The FPGA card was not properly initialised with the Pyro Server."
|
|
35
|
+
|
|
36
|
+
self.add_parameter('mem_hold', label='Memory Hold',
|
|
37
|
+
get_cmd=lambda : self._get('mem_hold'), vals=valids.Bool(),
|
|
38
|
+
set_cmd=lambda x : self._set('mem_hold', x), initial_value=False)
|
|
39
|
+
#!!!!!ONLY UserPin1 and UserPin4 are available in TVModeV02 !!!!!
|
|
40
|
+
#TODO: Tie the trigger port selection to this internally via the HAL later...
|
|
41
|
+
self.add_parameter('trigger_src_shot', label='Individual segment trigger',
|
|
42
|
+
get_cmd=lambda : self._get('trigger_src_shot'), vals=valids.Strings(),
|
|
43
|
+
set_cmd=lambda x : self._set('trigger_src_shot', x), initial_value='UserPin1')
|
|
44
|
+
self.add_parameter('trigger_src_ddc', label='DDC input trigger',
|
|
45
|
+
get_cmd=lambda : self._get('trigger_src_ddc'), vals=valids.Strings(),
|
|
46
|
+
set_cmd=lambda x : self._set('trigger_src_ddc', x), initial_value='UserPin1')
|
|
47
|
+
self.add_parameter('trigger_src_seq_start', label='Sequence start trigger',
|
|
48
|
+
get_cmd=lambda : self._get('trigger_src_seq_start'), vals=valids.Strings(),
|
|
49
|
+
set_cmd=lambda x : self._set('trigger_src_seq_start', x), initial_value='UserPin4')
|
|
50
|
+
|
|
51
|
+
#!!!!! Set small delays to avoid crosstalk !!!!! But what are the units?b
|
|
52
|
+
self.add_parameter('trigger_acq_delay', label='Trigger acquisition delay',
|
|
53
|
+
get_cmd=lambda : self._get('trigger_acq_delay'), vals=valids.Numbers(),
|
|
54
|
+
set_cmd=lambda x : self._set('trigger_acq_delay', x), initial_value=10.0)
|
|
55
|
+
self.add_parameter('trigger_pulse_delay', label='Trigger pulse delay',
|
|
56
|
+
get_cmd=lambda : self._get('trigger_pulse_delay'), vals=valids.Numbers(),
|
|
57
|
+
set_cmd=lambda x : self._set('trigger_pulse_delay', x), initial_value=10.0)
|
|
58
|
+
|
|
59
|
+
#25MHz IF, straight ADC mapping
|
|
60
|
+
self.add_parameter('ddc_adc1', label='ADC input for DDC1',
|
|
61
|
+
get_cmd=lambda : self._get('ddc_adc1'), vals=valids.Strings(),
|
|
62
|
+
set_cmd=lambda x : self._set('ddc_adc1', x), initial_value='ADC1')
|
|
63
|
+
self.add_parameter('ddc_adc2', label='ADC input for DDC2',
|
|
64
|
+
get_cmd=lambda : self._get('ddc_adc2'), vals=valids.Strings(),
|
|
65
|
+
set_cmd=lambda x : self._set('ddc_adc2', x), initial_value='ADC2')
|
|
66
|
+
self.add_parameter('ddc_if1', label='DDC1 IF downconversion frequency',
|
|
67
|
+
get_cmd=lambda : self._get('ddc_if1'), vals=valids.Strings(),
|
|
68
|
+
set_cmd=lambda x : self._set('ddc_if1', x), initial_value='25MHz')
|
|
69
|
+
self.add_parameter('ddc_if2', label='DDC2 IF downconversion frequency',
|
|
70
|
+
get_cmd=lambda : self._get('ddc_if2'), vals=valids.Strings(),
|
|
71
|
+
set_cmd=lambda x : self._set('ddc_if2', x), initial_value='25MHz')
|
|
72
|
+
|
|
73
|
+
#Default math: measure complex voltage
|
|
74
|
+
self.add_parameter('math_f1', label='Math function 1',
|
|
75
|
+
get_cmd=lambda : self._get('math_f1'), vals=valids.Strings(),
|
|
76
|
+
set_cmd=lambda x : self._set('math_f1', x), initial_value='1(a*b)')
|
|
77
|
+
self.add_parameter('math_f2', label='Math function 2',
|
|
78
|
+
get_cmd=lambda : self._get('math_f2'), vals=valids.Strings(),
|
|
79
|
+
set_cmd=lambda x : self._set('math_f2', x), initial_value='1(a*b)')
|
|
80
|
+
self.add_parameter('math_a1', label='Math function 1 argument format for a',
|
|
81
|
+
get_cmd=lambda : self._get('math_a1'), vals=valids.Strings(),
|
|
82
|
+
set_cmd=lambda x : self._set('math_a1', x), initial_value='I1 + iQ1')
|
|
83
|
+
self.add_parameter('math_a2', label='Math function 2 argument format for a',
|
|
84
|
+
get_cmd=lambda : self._get('math_a2'), vals=valids.Strings(),
|
|
85
|
+
set_cmd=lambda x : self._set('math_a2', x), initial_value='I2 + iQ2')
|
|
86
|
+
self.add_parameter('math_b1', label='Math function 1 argument format for b',
|
|
87
|
+
get_cmd=lambda : self._get('math_b1'), vals=valids.Strings(),
|
|
88
|
+
set_cmd=lambda x : self._set('math_b1', x), initial_value='1*')
|
|
89
|
+
self.add_parameter('math_b2', label='Math function 2 argument format for b',
|
|
90
|
+
get_cmd=lambda : self._get('math_b2'), vals=valids.Strings(),
|
|
91
|
+
set_cmd=lambda x : self._set('math_b2', x), initial_value='1*')
|
|
92
|
+
|
|
93
|
+
#Boxcar FIR filter (refine with ctx_fpga_fir)
|
|
94
|
+
self.add_parameter('fir_engine', label='FIR filter type',
|
|
95
|
+
get_cmd=lambda : self._get('fir_engine'), vals=valids.Strings(),
|
|
96
|
+
set_cmd=lambda x : self._set('fir_engine', x), initial_value='boxcar')
|
|
97
|
+
self.add_parameter('fir_integration', label='FIR integration',
|
|
98
|
+
get_cmd=lambda : self._get('fir_integration'), vals=valids.Strings(),
|
|
99
|
+
set_cmd=lambda x : self._set('fir_integration', x), initial_value='none')
|
|
100
|
+
self.add_parameter('fir_post_filtering', label='FIR post filtering enable',
|
|
101
|
+
get_cmd=lambda : self._get('fir_post_filtering'), vals=valids.Bool(),
|
|
102
|
+
set_cmd=lambda x : self._set('fir_post_filtering', x), initial_value=False)
|
|
103
|
+
|
|
104
|
+
#TODO: MAKE THESE HIGHER LEVEL PARAMETERS
|
|
105
|
+
self.add_parameter('tv_decimation', label='Decimation downsampling factor on TV mode',
|
|
106
|
+
get_cmd=lambda : self._get('tv_decimation'), vals=valids.Ints(),
|
|
107
|
+
set_cmd=lambda x : self._set('tv_decimation', x), initial_value=4)
|
|
108
|
+
self.add_parameter('tv_averages', label='Number of TV averages',
|
|
109
|
+
get_cmd=lambda : self._get('tv_averages'), vals=valids.Ints(),
|
|
110
|
+
set_cmd=lambda x : self._set('tv_averages', x), initial_value=1024)
|
|
111
|
+
|
|
112
|
+
self.add_parameter('tv_use_seq_start', label='Use the sequence start trigger in cases of multiple segments',
|
|
113
|
+
get_cmd=lambda : self._get('tv_use_seq_start'), vals=valids.Bool(),
|
|
114
|
+
set_cmd=lambda x : self._set('tv_use_seq_start', x), initial_value=False)
|
|
115
|
+
|
|
116
|
+
self.add_parameter('tv_two_channel_mode', label='Enable 2-channel TV mode',
|
|
117
|
+
get_cmd=lambda : self._get('tv_two_channel_mode'), vals=valids.Bool(),
|
|
118
|
+
set_cmd=lambda x : self._set('tv_two_channel_mode', x), initial_value=False)
|
|
119
|
+
|
|
120
|
+
self._set_default(app_name)
|
|
121
|
+
|
|
122
|
+
self._ch_states = (True, False)
|
|
123
|
+
self._num_segs = 1
|
|
124
|
+
self._num_reps = 1
|
|
125
|
+
self._trigger_edge = 1
|
|
126
|
+
self._num_samples = 1
|
|
127
|
+
self._last_dsp_state = None
|
|
128
|
+
|
|
129
|
+
def get_idn(self):
|
|
130
|
+
return {
|
|
131
|
+
"vendor": "ETH",
|
|
132
|
+
"model": str(self.__class__),
|
|
133
|
+
"serial": "NA",
|
|
134
|
+
"firmware": "NA"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
def _set_default(self, app_name = 'TVMODEV02'):
|
|
138
|
+
self._set_app(app_name)
|
|
139
|
+
|
|
140
|
+
''' program a chebychev low-pass filter with a given bandwidth and gain '''
|
|
141
|
+
bandwidth=0.1
|
|
142
|
+
gain=1.0
|
|
143
|
+
bandwidths = [0.001, 0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.14, 0.16, 0.18,
|
|
144
|
+
0.2, 0.22, 0.24, 0.26, 0.28, 0.3, 0.32, 0.34, 0.36, 0.38, 0.4]
|
|
145
|
+
bandwidth = min(bandwidths, key=lambda x: abs(x - bandwidth))
|
|
146
|
+
# exclude parameters that are not present in the current mode
|
|
147
|
+
self._set('fir_engine', 'library')
|
|
148
|
+
self._set('fir_library_file', r'C:/QTLab/custom_plugins/FPGA/filters/chebLP_ASYM40_FilterLib001.txt')
|
|
149
|
+
self._set('fir_filter', 'lp fs={0:g} 40tap cheb(g=2.5)'.format(bandwidth))
|
|
150
|
+
self._set('fir_gain1', gain)
|
|
151
|
+
self._set('fir_gain2', gain)
|
|
152
|
+
|
|
153
|
+
def _set_fir(self, gain=1.0, bandwidth=0.1):
|
|
154
|
+
''' program a chebychev low-pass filter with a given bandwidth and gain '''
|
|
155
|
+
# bandwidth=0.1
|
|
156
|
+
# gain=1.0
|
|
157
|
+
bandwidths = [0.001, 0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.14, 0.16, 0.18,
|
|
158
|
+
0.2, 0.22, 0.24, 0.26, 0.28, 0.3, 0.32, 0.34, 0.36, 0.38, 0.4]
|
|
159
|
+
bandwidth = min(bandwidths, key=lambda x: abs(x - bandwidth))
|
|
160
|
+
# exclude parameters that are not present in the current mode
|
|
161
|
+
self._set('fir_engine', 'library')
|
|
162
|
+
self._set('fir_library_file', r'C:/QTLab/custom_plugins/FPGA/filters/chebLP_ASYM40_FilterLib001.txt')
|
|
163
|
+
self._set('fir_filter', 'lp fs={0:g} 40tap cheb(g=2.5)'.format(bandwidth))
|
|
164
|
+
self._set('fir_gain1', gain)
|
|
165
|
+
self._set('fir_gain2', gain)
|
|
166
|
+
|
|
167
|
+
def _set_app(self, appname):
|
|
168
|
+
result = self._proxy.set_app(self._remote_name, appname)
|
|
169
|
+
if appname == 'TVMODEV02':
|
|
170
|
+
self._call('set_app', 'TVMODEV02')
|
|
171
|
+
|
|
172
|
+
self._set('mem_hold', False),
|
|
173
|
+
self._set('ddc_adc1', 'ADC1')
|
|
174
|
+
self._set('ddc_if1', '25MHz') ### Eric changed to 10 MHz
|
|
175
|
+
self._set('ddc_adc2', 'ADC2')
|
|
176
|
+
self._set('ddc_if2', '25MHz') ### Eric changed to 10 MHz
|
|
177
|
+
# default math: measure complex voltage
|
|
178
|
+
self._set('math_f1', '1(a*b)')
|
|
179
|
+
self._set('math_a1', 'I1 + iQ1')
|
|
180
|
+
self._set('math_b1', '1*')
|
|
181
|
+
self._set('math_f2', '1(a*b)')
|
|
182
|
+
self._set('math_a2', 'I2 + iQ2')
|
|
183
|
+
self._set('math_b2', '1*')
|
|
184
|
+
# boxcar FIR filter (refine with ctx_fpga_fir)
|
|
185
|
+
self._set('fir_engine', 'boxcar')
|
|
186
|
+
self._set('fir_integration', 'none')
|
|
187
|
+
self._set('fir_post_filtering', False)
|
|
188
|
+
# tv mode: 248 samples, 40ns per sample, <~ 10us per trace
|
|
189
|
+
self._set('tv_decimation', 4)
|
|
190
|
+
self._set('tv_samples', 4096)
|
|
191
|
+
self._set('tv_averages', 1)
|
|
192
|
+
# tv mode: one segment, one channel
|
|
193
|
+
self._set('tv_segments', 1)
|
|
194
|
+
self._set('tv_use_seq_start', False)
|
|
195
|
+
return result
|
|
196
|
+
|
|
197
|
+
def _get(self, pname, **kwargs):
|
|
198
|
+
"""Query value of parameter `pname`. kwargs are ignored."""
|
|
199
|
+
return self._proxy.ins_get(self._remote_name, pname, kwargs)
|
|
200
|
+
|
|
201
|
+
def _set(self, pname, *args, **kwargs):
|
|
202
|
+
"""Set value of parameter `pname` to `value`. kwargs are ignored."""
|
|
203
|
+
return self._proxy.ins_set(self._remote_name, pname, args, kwargs)
|
|
204
|
+
|
|
205
|
+
def _call(self, pname, *args, **kwargs):
|
|
206
|
+
result = self._proxy.ins_call(self._remote_name, pname, args, kwargs)
|
|
207
|
+
# return result
|
|
208
|
+
try:
|
|
209
|
+
return pickle.loads(bytes(result, encoding='utf-8'), encoding='bytes')
|
|
210
|
+
except TypeError:
|
|
211
|
+
return result
|
|
212
|
+
except pickle.UnpicklingError:
|
|
213
|
+
return result
|
|
214
|
+
|
|
215
|
+
def __dir__(self):
|
|
216
|
+
'''
|
|
217
|
+
Get available parameters...
|
|
218
|
+
'''
|
|
219
|
+
attrs = []#dir(super(ETHFPGA, self))
|
|
220
|
+
attrs += self._proxy.get_parameter_names(self._remote_name)
|
|
221
|
+
attrs += self._proxy.get_function_names(self._remote_name)
|
|
222
|
+
return list(set(attrs))
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def ChannelStates(self):
|
|
226
|
+
return self._ch_states
|
|
227
|
+
@ChannelStates.setter
|
|
228
|
+
def ChannelStates(self, ch_states):
|
|
229
|
+
assert len(ch_states) == 2, "There are 2 channel states that must be specified."
|
|
230
|
+
assert ch_states[0] != False, "This instrument only supports either CH1 or CH1&CH2 modes."
|
|
231
|
+
|
|
232
|
+
self._set('tv_two_channel_mode', ch_states[1])
|
|
233
|
+
self._ch_states = ch_states
|
|
234
|
+
|
|
235
|
+
@property
|
|
236
|
+
def AvailableChannels(self):
|
|
237
|
+
return 2
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def SampleRate(self):
|
|
241
|
+
return 100e6
|
|
242
|
+
@SampleRate.setter
|
|
243
|
+
def SampleRate(self, frequency_hertz):
|
|
244
|
+
assert frequency_hertz == 100e6, "ETH FPGA Card only supports 100MSPS sample rate."
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def NumSamples(self):
|
|
248
|
+
return self._num_samples
|
|
249
|
+
@NumSamples.setter
|
|
250
|
+
def NumSamples(self, num_samples):
|
|
251
|
+
self._num_samples = num_samples
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def NumSegments(self):
|
|
255
|
+
return self._num_segs
|
|
256
|
+
@NumSegments.setter
|
|
257
|
+
def NumSegments(self, num_segs):
|
|
258
|
+
self._num_segs = num_segs
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def NumRepetitions(self):
|
|
262
|
+
return self._num_reps
|
|
263
|
+
@NumRepetitions.setter
|
|
264
|
+
def NumRepetitions(self, num_reps):
|
|
265
|
+
self._num_reps = num_reps
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def TriggerInputEdge(self):
|
|
269
|
+
return self._trigger_edge
|
|
270
|
+
@TriggerInputEdge.setter
|
|
271
|
+
def TriggerInputEdge(self, pol):
|
|
272
|
+
self._trigger_edge = 1 #Always setting to positive edge...
|
|
273
|
+
#self._trigger_edge = pol #TODO: Check if input trigger polarity can be set on this instrument
|
|
274
|
+
|
|
275
|
+
@property
|
|
276
|
+
def SupportedDecisionBlocks(self):
|
|
277
|
+
return []
|
|
278
|
+
|
|
279
|
+
#TODO: WRITE A DDC PROPERTY - look up ddc_if2 and ddc_adc1 as well...
|
|
280
|
+
# @property
|
|
281
|
+
# def DdcIfFrequency(self):
|
|
282
|
+
# return self._get('ddc_adc1')
|
|
283
|
+
# @DdcIfFrequency.setter
|
|
284
|
+
# def DdcIfFrequency(self, freqHertz):
|
|
285
|
+
# self._set('ddc_adc1', freqHertz)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# @property
|
|
289
|
+
# def TriggerInputEdge(self):
|
|
290
|
+
# return 1 #Always positive edge
|
|
291
|
+
# @TriggerInputEdge.setter
|
|
292
|
+
# def TriggerInputEdge(self, pol):
|
|
293
|
+
# self._trigger_edge = pol
|
|
294
|
+
|
|
295
|
+
def _start(self, **kwargs):
|
|
296
|
+
self._set('trigger_src_shot',0) #Sample Trigger
|
|
297
|
+
self._set('trigger_src_ddc',0) #DDC Trigger (it means something)
|
|
298
|
+
|
|
299
|
+
if self.NumSegments > 1:
|
|
300
|
+
#Set SEQ Trigger Mode
|
|
301
|
+
self._set('tv_use_seq_start',True)
|
|
302
|
+
self._set('trigger_src_seq_start', 3) #Using User Pin 4 for SEQ Trigger
|
|
303
|
+
else:
|
|
304
|
+
self._set('tv_use_seq_start',False)
|
|
305
|
+
self._set('trigger_src_seq_start', 0)
|
|
306
|
+
|
|
307
|
+
total_frames = self._cur_reps*self.NumSegments
|
|
308
|
+
self._set('tv_segments', total_frames)
|
|
309
|
+
self._call('stop')
|
|
310
|
+
self._call('mem_clear')
|
|
311
|
+
|
|
312
|
+
def _acquire(self):
|
|
313
|
+
#channels, segments, samples
|
|
314
|
+
return self._call('get_data_blocking')
|
|
315
|
+
|
|
316
|
+
def _stop(self, final_data, **kwargs):
|
|
317
|
+
cur_processor = kwargs.get('data_processor', None)
|
|
318
|
+
cap_samples = kwargs.get('cap_samples')
|
|
319
|
+
channels, segments, samples = final_data.shape
|
|
320
|
+
|
|
321
|
+
leSampleRate = self._call('get_sample_rate') / self.tv_decimation()
|
|
322
|
+
|
|
323
|
+
if channels == 1:
|
|
324
|
+
ch1_data = final_data[0].reshape(self._cur_reps, self.NumSegments, cap_samples)
|
|
325
|
+
data_pkt = {
|
|
326
|
+
'parameters' : ['repetition', 'segment', 'sample'],
|
|
327
|
+
'data' : { 'ch1_I' : np.real(ch1_data), 'ch1_Q' : np.imag(ch1_data) },
|
|
328
|
+
'misc' : {'SampleRates' : [leSampleRate]*2}
|
|
329
|
+
}
|
|
330
|
+
else:
|
|
331
|
+
ch1_data = final_data[0].reshape(self._cur_reps, self.NumSegments, cap_samples)
|
|
332
|
+
ch2_data = final_data[1].reshape(self._cur_reps, self.NumSegments, cap_samples)
|
|
333
|
+
data_pkt = {
|
|
334
|
+
'parameters' : ['repetition', 'segment', 'sample'],
|
|
335
|
+
'data' : { 'ch1_I' : np.real(ch1_data), 'ch1_Q' : np.imag(ch1_data),
|
|
336
|
+
'ch2_I' : np.real(ch2_data), 'ch2_Q' : np.imag(ch2_data) },
|
|
337
|
+
'misc' : {'SampleRates' : [leSampleRate]*4}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if cur_processor is None or isinstance(cur_processor, ProcessorFPGA):
|
|
341
|
+
return data_pkt
|
|
342
|
+
else:
|
|
343
|
+
cur_processor.push_data(data_pkt)
|
|
344
|
+
return None
|
|
345
|
+
|
|
346
|
+
def get_data(self, **kwargs):
|
|
347
|
+
max_memory = 2**19
|
|
348
|
+
|
|
349
|
+
cur_processor = kwargs.get('data_processor', None)
|
|
350
|
+
|
|
351
|
+
if not isinstance(cur_processor, ProcessorFPGA) or not cur_processor.compare_pipeline_state(self._last_dsp_state):
|
|
352
|
+
self._hw_avg = False
|
|
353
|
+
self._hw_int = False
|
|
354
|
+
self._hw_intSg = False
|
|
355
|
+
self._last_dsp_state = {}
|
|
356
|
+
if isinstance(cur_processor, ProcessorFPGA) and not cur_processor.compare_pipeline_state(self._last_dsp_state):
|
|
357
|
+
ddc_done = False
|
|
358
|
+
fir_done = False
|
|
359
|
+
deci_done = False
|
|
360
|
+
avg_done = False
|
|
361
|
+
int_done = False
|
|
362
|
+
intSg_done = False
|
|
363
|
+
for m, cur_node in enumerate(cur_processor.pipeline):
|
|
364
|
+
if isinstance(cur_node, FPGA_DDC):
|
|
365
|
+
assert not ddc_done, "Cannot run multiple DDC stages on the ETH FPGA card."
|
|
366
|
+
assert not fir_done, "Cannot run DDC after FIR stage on the ETH FPGA card."
|
|
367
|
+
assert not deci_done, "Cannot run DDC after Decimation stage on the ETH FPGA card."
|
|
368
|
+
assert not avg_done, "Cannot run DDC after Averaging stage on the ETH FPGA card."
|
|
369
|
+
assert not int_done, "Cannot run DDC after Integration stage on the ETH FPGA card."
|
|
370
|
+
assert not intSg_done, "Cannot run DDC after Integration stage on the ETH FPGA card."
|
|
371
|
+
ddc_specs = cur_node.get_params(sample_rate = [100e6]*2, only_params=True)
|
|
372
|
+
assert len(ddc_specs) > 0, "Cannot run DDC without any frequencies"
|
|
373
|
+
assert len(ddc_specs[0]) <= 1, "ETH FPGA can only demodulate one tone per channel."
|
|
374
|
+
if len(ddc_specs[0]) == 1:
|
|
375
|
+
assert ddc_specs[0][0] == 25e6 or ddc_specs[0][0] == 10e6, "ETH FPGA can only demodulate 10MHz or 25MHz tones."
|
|
376
|
+
#Program 1st channel DDC
|
|
377
|
+
self._set('ddc_adc1', 'ADC1')
|
|
378
|
+
self._set('ddc_if1', f'{int(ddc_specs[0][0]/1e6)}MHz')
|
|
379
|
+
if len(ddc_specs) == 2:
|
|
380
|
+
assert len(ddc_specs[1]) == 1, "ETH FPGA can only demodulate one tone per channel."
|
|
381
|
+
assert ddc_specs[1][0] == 25e6 or ddc_specs[1][0] == 10e6, "ETH FPGA can only demodulate 10MHz or 25MHz tones."
|
|
382
|
+
self._set('ddc_adc2', 'ADC2')
|
|
383
|
+
self._set('ddc_if2', f'{int(ddc_specs[1][0]/1e6)}MHz')
|
|
384
|
+
ddc_done = True
|
|
385
|
+
elif isinstance(cur_node, FPGA_FIR):
|
|
386
|
+
assert not fir_done, "Cannot run multiple FIR stages on the ETH FPGA card."
|
|
387
|
+
assert not deci_done, "Cannot run FIR after Decimation stage on the ETH FPGA card."
|
|
388
|
+
assert not avg_done, "Cannot run FIR after Averaging stage on the ETH FPGA card."
|
|
389
|
+
assert not int_done, "Cannot run FIR after Integration stage on the ETH FPGA card."
|
|
390
|
+
assert not intSg_done, "Cannot run FIR after Integration stage on the ETH FPGA card."
|
|
391
|
+
fir_specs = cur_node.get_params(sample_rate = [100e6]*2)
|
|
392
|
+
assert len(fir_specs) > 0, "FIR list invalid"
|
|
393
|
+
assert len(fir_specs[0]) <= 1, "ETH FPGA can only filter one tone per channel."
|
|
394
|
+
if len(fir_specs[0]) == 1:
|
|
395
|
+
num_taps = fir_specs[0][0].size
|
|
396
|
+
assert num_taps == 7 or num_taps == 29 or num_taps == 40, "FIR filter taps must be either 7, 29 or 4"
|
|
397
|
+
self._call('set_fir_coeffs', fir_specs[0][0].tolist())
|
|
398
|
+
if len(fir_specs) == 2:
|
|
399
|
+
assert len(fir_specs[1]) == 1, "ETH FPGA can only filter one tone per channel."
|
|
400
|
+
num_taps2 = fir_specs[1][0].size
|
|
401
|
+
assert num_taps2 == 7 or num_taps2 == 29 or num_taps2 == 40, "FIR filter taps must be either 7, 29 or 4"
|
|
402
|
+
if len(fir_specs[0]) == 1:
|
|
403
|
+
assert num_taps == num_taps2, "The ETH FPGA must use the same FIR filter on both channels."
|
|
404
|
+
assert np.sum(np.abs(fir_specs[0][0] - fir_specs[1][0])) < 1e-9, "The ETH FPGA must use the same FIR filter coefficients on both channels."
|
|
405
|
+
else:
|
|
406
|
+
self._call('set_fir_coeffs', fir_specs[1][0].tolist())
|
|
407
|
+
fir_done = True
|
|
408
|
+
elif isinstance(cur_node, FPGA_Decimation):
|
|
409
|
+
assert not deci_done, "Cannot run Decimation FIR stages on the ETH FPGA card."
|
|
410
|
+
assert not avg_done, "Cannot run Decimation after Averaging stage on the ETH FPGA card."
|
|
411
|
+
assert not int_done, "Cannot run Decimation after Integration stage on the ETH FPGA card."
|
|
412
|
+
assert not intSg_done, "Cannot run Decimation after Integration stage on the ETH FPGA card."
|
|
413
|
+
param, fac = cur_node.get_params()
|
|
414
|
+
assert param == 'sample', "The ETH FPGA only supports decimation samples."
|
|
415
|
+
assert fac <= 128 and fac >= 1, "The ETH FPGA only supports decimation of up to 128 points."
|
|
416
|
+
self._set('tv_decimation', fac)
|
|
417
|
+
deci_done = True
|
|
418
|
+
elif isinstance(cur_node, FPGA_Mean):
|
|
419
|
+
assert not avg_done, "Cannot run multiple averaging stages on the ETH FPGA card."
|
|
420
|
+
param = cur_node.get_params()
|
|
421
|
+
assert param == 'repetition', "Currently the ETH FPGA card only supports averaging across repetitions."
|
|
422
|
+
self._set('tv_averages', self.NumRepetitions)
|
|
423
|
+
self._hw_avg = True
|
|
424
|
+
avg_done = True
|
|
425
|
+
elif isinstance(cur_node, FPGA_Integrate):
|
|
426
|
+
assert not int_done or not intSg_done, "Cannot run multiple integration stages on the ETH FPGA card."
|
|
427
|
+
param = cur_node.get_params()
|
|
428
|
+
assert param == 'sample' or param == 'segment', "Currently the ETH FPGA card only supports integration across samples or segments (albeit, not in hardware for segments)."
|
|
429
|
+
if param == 'sample':
|
|
430
|
+
self._hw_int = True
|
|
431
|
+
else:
|
|
432
|
+
self._hw_intSg = True
|
|
433
|
+
int_done = True
|
|
434
|
+
|
|
435
|
+
if not ddc_done:
|
|
436
|
+
self._set('ddc_adc1', 'ADC1')
|
|
437
|
+
self._set('ddc_if1', 'DC')
|
|
438
|
+
self._set('ddc_adc2', 'ADC2')
|
|
439
|
+
self._set('ddc_if2', 'DC')
|
|
440
|
+
if not fir_specs:
|
|
441
|
+
self._call('set_fir_coeffs', [])
|
|
442
|
+
if not deci_done:
|
|
443
|
+
self._set('tv_decimation', 1)
|
|
444
|
+
if not avg_done:
|
|
445
|
+
self._set('tv_averages',1)
|
|
446
|
+
self._last_dsp_state = cur_processor.get_pipeline_state()
|
|
447
|
+
time.sleep(1)
|
|
448
|
+
if self._hw_avg:
|
|
449
|
+
self._set('tv_averages',self.NumRepetitions)
|
|
450
|
+
|
|
451
|
+
#The ETH FPGA Card expects the tv_samples to be the number AFTER decimation.
|
|
452
|
+
actual_samples = self.NumSamples
|
|
453
|
+
deci_fac = self._get('tv_decimation')
|
|
454
|
+
cap_samples = int(self.NumSamples / deci_fac)
|
|
455
|
+
self._set('tv_samples', cap_samples)
|
|
456
|
+
kwargs['cap_samples'] = cap_samples
|
|
457
|
+
#
|
|
458
|
+
if self._hw_avg:
|
|
459
|
+
actual_reps = 1
|
|
460
|
+
else:
|
|
461
|
+
actual_reps = self.NumRepetitions
|
|
462
|
+
|
|
463
|
+
total_samples_captured = cap_samples * self.NumSegments * actual_reps
|
|
464
|
+
if total_samples_captured > max_memory:
|
|
465
|
+
assert isinstance(cur_processor, ProcessorFPGA), "Exceeded ETH FPGA memory - check the FPGA processing and ACQ capture parameters."
|
|
466
|
+
max_rep = int(max_memory / (cap_samples * self.NumSegments))
|
|
467
|
+
assert max_rep > 0, "Too many samples to capture in a single shot."
|
|
468
|
+
|
|
469
|
+
cur_reps = 0
|
|
470
|
+
# data_pkts = []
|
|
471
|
+
while cur_reps < actual_reps:
|
|
472
|
+
self._cur_reps = min(max_rep, actual_reps - cur_reps)
|
|
473
|
+
cur_reps += self._cur_reps
|
|
474
|
+
|
|
475
|
+
self._start(**kwargs)
|
|
476
|
+
#channels, segments, samples
|
|
477
|
+
final_data = self._acquire()
|
|
478
|
+
self._stop(final_data, **kwargs)
|
|
479
|
+
if cur_processor is None:
|
|
480
|
+
assert False, "NumRepetitions exceeds memory. Multiple capture method has only been implemented for the case where a data_processor is supplied."
|
|
481
|
+
# return data_pkt
|
|
482
|
+
else:
|
|
483
|
+
return {'data': cur_processor.get_all_data()}
|
|
484
|
+
else:
|
|
485
|
+
self._cur_reps = actual_reps
|
|
486
|
+
self._start(**kwargs)
|
|
487
|
+
#channels, segments, samples
|
|
488
|
+
final_data = self._acquire()
|
|
489
|
+
data_pkt = self._stop(final_data, **kwargs)
|
|
490
|
+
if cur_processor is None or isinstance(cur_processor, ProcessorFPGA):
|
|
491
|
+
#Contract out the repetition index if hardware averaging...
|
|
492
|
+
if self._hw_avg:
|
|
493
|
+
data_pkt['parameters'].pop(0)
|
|
494
|
+
for cur_ch in data_pkt['data']:
|
|
495
|
+
data_pkt['data'][cur_ch] = data_pkt['data'][cur_ch][0]
|
|
496
|
+
#TODO: SUPPORT HARDWARE INTEGRATION. Apparently it is present. c.f. mod_fir in the QT Lab stuff.
|
|
497
|
+
if self._hw_int:
|
|
498
|
+
axs = data_pkt['parameters'].index('sample')
|
|
499
|
+
data_pkt['parameters'].pop(axs)
|
|
500
|
+
for cur_ch in data_pkt['data']:
|
|
501
|
+
data_pkt['data'][cur_ch] = np.sum(data_pkt['data'][cur_ch], axis=axs)
|
|
502
|
+
if self._hw_intSg:
|
|
503
|
+
axs = data_pkt['parameters'].index('segment')
|
|
504
|
+
data_pkt['parameters'].pop(axs)
|
|
505
|
+
for cur_ch in data_pkt['data']:
|
|
506
|
+
data_pkt['data'][cur_ch] = np.sum(data_pkt['data'][cur_ch], axis=axs)
|
|
507
|
+
return {'data': data_pkt}
|
|
508
|
+
else:
|
|
509
|
+
return {'data': cur_processor.get_all_data()}
|