Source code for seq.noise

"""
@author: J.M. Algarín, february 03th 2022
MRILAB @ I3M
"""

import os
import sys
import time

#*****************************************************************************
# Get the directory of the current script
main_directory = os.path.dirname(os.path.realpath(__file__))
parent_directory = os.path.dirname(main_directory)
parent_directory = os.path.dirname(parent_directory)

# Define the subdirectories you want to add to sys.path
subdirs = ['MaRGE', 'marcos_client']

# Add the subdirectories to sys.path
for subdir in subdirs:
    full_path = os.path.join(parent_directory, subdir)
    sys.path.append(full_path)
#******************************************************************************
import controller.experiment_gui as ex
import numpy as np
import seq.mriBlankSeq as blankSeq  # Import the mriBlankSequence for any new sequence.
import configs.hw_config as hw
import configs.units as units

[docs] class Noise(blankSeq.MRIBLANKSEQ): def __init__(self): super(Noise, self).__init__() # Input the parameters self.repetitionTime = None self.rxChannel = None self.nPoints = None self.bw = None self.freqOffset = None self.addParameter(key='seqName', string='NoiseInfo', val='Noise') self.addParameter(key='freqOffset', string='RF frequency offset (kHz)', val=0.0, units=units.kHz, field='RF') self.addParameter(key='nPoints', string='Number of points', val=2500, field='RF') self.addParameter(key='bw', string='Acquisition bandwidth (kHz)', val=50.0, units=units.kHz, field='RF') self.addParameter(key='rxChannel', string='Rx channel', val=0, field='RF') self.addParameter(key='repetitionTime', string='Repetition time (ms)', val=500.0, field='RF', units=units.ms)
[docs] def sequenceInfo(self): print("Noise") print("Author: Dr. J.M. Algarín") print("Contact: josalggui@i3m.upv.es") print("mriLab @ i3M, CSIC, Spain") print("Get a noise measurement\n")
[docs] def sequenceTime(self): return(0) # minutes, scanTime
[docs] def sequenceRun(self, plotSeq=0, demo=False): init_gpa = False self.demo = demo # Fix units to MHz and us self.freqOffset *= 1e-6 # MHz self.bw *= 1e-6 # MHz self.repetitionTime *= 1e6 # us self.mapVals['larmorFreq'] = hw.larmorFreq if self.demo: dataR = np.random.randn((self.nPoints + 2 * hw.addRdPoints) * hw.oversamplingFactor) dataC = np.random.randn((self.nPoints + 2 * hw.addRdPoints) * hw.oversamplingFactor) data = dataR+1j*dataC data = self.decimate(data_over=data, n_adc=1, option='Normal') acqTime = self.nPoints/self.bw tVector = np.linspace(0, acqTime, num=self.nPoints) * 1e-3 # ms spectrum = np.fft.ifftshift(np.fft.ifftn(np.fft.ifftshift(data))) fVector = np.linspace(-self.bw / 2, self.bw / 2, num=self.nPoints) * 1e3 # kHz self.dataTime = [tVector, data] self.dataSpec = [fVector, spectrum] time.sleep(self.repetitionTime*1e-6) else: samplingPeriod = 1 / self.bw self.expt = ex.Experiment(lo_freq=hw.larmorFreq + self.freqOffset, rx_t=samplingPeriod, init_gpa=init_gpa, gpa_fhdo_offset_time=(1 / 0.2 / 3.1), print_infos=False) samplingPeriod = self.expt.getSamplingRate() self.bw = 1/samplingPeriod acqTime = self.nPoints/self.bw # SEQUENCE self.iniSequence(20, np.array((0, 0, 0))) t0 = 30 + hw.addRdPoints*hw.oversamplingFactor/self.bw self.rxGateSync(t0, acqTime, channel=self.rxChannel) t0 = t0 + acqTime + hw.addRdPoints*hw.oversamplingFactor/self.bw if t0 < self.repetitionTime: self.endSequence(self.repetitionTime) else: self.endSequence(t0+20) # Load sequence to red pitaya if self.floDict2Exp(): print("Sequence waveforms loaded successfully") pass else: print("ERROR: sequence waveforms out of hardware bounds") return False if plotSeq == 0: rxd, msgs = self.expt.run() data = self.decimate(rxd['rx%i' % self.rxChannel], 1, option='Normal') self.mapVals['data'] = data tVector = np.linspace(0, acqTime, num=self.nPoints) * 1e-3 # ms spectrum = np.fft.ifftshift(np.fft.ifftn(np.fft.ifftshift(data))) fVector = np.linspace(-self.bw / 2, self.bw / 2, num=self.nPoints) * 1e3 # kHz self.dataTime = [tVector, data] self.dataSpec = [fVector, spectrum] self.expt.__del__() return True
[docs] def sequenceAnalysis(self, mode=None): self.mode = mode noiserms = np.std(self.dataTime[1]) self.mapVals['RMS noise'] = noiserms self.mapVals['sampledPoint'] = noiserms # for sweep method noiserms = noiserms*1e3 print('rms noise: %0.5f uV' % noiserms) bw = self.mapVals['bw']*1e3 # Hz johnson = np.sqrt(2 * 50 * hw.temperature * bw * 1.38e-23) * 10 ** (hw.lnaGain / 20) * 1e6 # uV print('Expected by Johnson: %0.5f uV' % johnson) # Plot signal versus time result1 = {'widget': 'curve', 'xData': self.dataTime[0], 'yData': [np.abs(self.dataTime[1]), np.real(self.dataTime[1]), np.imag(self.dataTime[1])], 'xLabel': 'Time (ms)', 'yLabel': 'Signal amplitude (mV)', 'title': 'Noise vs time', 'legend': ['abs', 'real', 'imag'], 'row': 0, 'col': 0} # Plot spectrum result2 = {'widget': 'curve', 'xData': self.dataSpec[0], 'yData': [np.abs(self.dataSpec[1])], 'xLabel': 'Frequency (kHz)', 'yLabel': 'Mag FFT (a.u.)', 'title': 'Noise spectrum', 'legend': [''], 'row': 1, 'col': 0} self.output = [result1, result2] self.saveRawData() if self.mode == 'Standalone': self.plotResults() # #################### # dataOver = self.mapVals['dataOver'] # plt.plot(np.real(dataOver)) # plt.plot(np.imag(dataOver)) # plt.show() return self.output
if __name__=='__main__': seq = Noise() seq.sequenceAtributes() seq.sequenceRun(demo=True) seq.sequenceAnalysis(mode='Standalone')