Source code for seq.fid

"""
@author: José Miguel Algarín Guisado
MRILAB @ I3M
"""

import os
import sys
#*****************************************************************************
# 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 scipy.signal as sig
import configs.hw_config as hw
import configs.units as units

[docs] class FID(blankSeq.MRIBLANKSEQ): def __init__(self): super(FID, self).__init__() # Input the parameters self.addParameter(key='seqName', string='FIDinfo', val='FID') self.addParameter(key='nScans', string='Number of scans', val=1, field='RF') self.addParameter(key='larmorFreq', string='Larmor frequency (MHz)', val=3.08, field='RF') self.addParameter(key='rfExAmp', string='RF excitation amplitude (a.u.)', val=0.3, field='RF') self.addParameter(key='rfExTime', string='RF excitation time (us)', val=30.0, field='RF') self.addParameter(key='deadTime', string='RF dead time (us)', val=400.0, field='RF') self.addParameter(key='repetitionTime', string='Repetition time (ms)', val=1000., field='SEQ') self.addParameter(key='acqTime', string='Acquisition time (ms)', val=4.0, field='SEQ') self.addParameter(key='nPoints', string='Number of points', val=100, field='IM') self.addParameter(key='shimming', string='Shimming (*1e4)', val=[-70, -90, 10], field='OTH') self.addParameter(key='txChannel', string='Tx channel', val=0, field='RF') self.addParameter(key='rxChannel', string='Rx channel', val=0, field='RF') self.addParameter(key='shimmingTime', string='Shimming time (ms)', val=1, field='OTH') self.addParameter(key='readRFpulse', string='Read RF Pulse', val=0, field='OTH')
[docs] def sequenceInfo(self): print("FID") print("Author: Dr. J.M. Algarín") print("Contact: josalggui@i3m.upv.es") print("mriLab @ i3M, CSIC, Spain") print("This sequence runs a single FID\n")
[docs] def sequenceTime(self): nScans = self.mapVals['nScans'] repetitionTime = self.mapVals['repetitionTime']*1e-3 return(repetitionTime*nScans/60) # minutes, scanTime
[docs] def sequenceRun(self, plotSeq=0, demo=False): init_gpa = False # Starts the gpa # Create input parameters nScans = self.mapVals['nScans'] larmorFreq = self.mapVals['larmorFreq'] # MHz rfExAmp = self.mapVals['rfExAmp'] rfExTime = self.mapVals['rfExTime'] # us deadTime = self.mapVals['deadTime'] # us repetitionTime = self.mapVals['repetitionTime']*1e3 # us acqTime = self.mapVals['acqTime']*1e3 # us nPoints = self.mapVals['nPoints'] shimming = np.array(self.mapVals['shimming'])*units.sh txChannel = self.mapVals['txChannel'] rxChannel = self.mapVals['rxChannel'] shimmingTime = self.mapVals['shimmingTime']*1e3 # us # Miscellaneus bw = nPoints/acqTime # MHz def createSequence(): # Shimming self.iniSequence(20, shimming) # shimming is turned on 20 us after experiment beginning for scan in range(nScans): tEx = shimmingTime + repetitionTime*scan + hw.blkTime + rfExTime / 2 # Excitation pulse t0 = tEx - hw.blkTime - rfExTime / 2 self.rfRecPulse(t0, rfExTime, rfExAmp, 0, channel=txChannel) # Rx gate if self.readRFpulse == 0: t0 = tEx + rfExTime / 2 + deadTime elif self.readRFpulse == 1: t0 = tEx-rfExTime/2 self.rxGateSync(t0, acqTime, channel=rxChannel) # self.ttl(t0, acqTime, channel=1, rewrite=True) self.endSequence(shimmingTime + repetitionTime*nScans) # Initialize the experiment samplingPeriod = 1 / bw # us self.expt = ex.Experiment(lo_freq=larmorFreq, rx_t=samplingPeriod, init_gpa=init_gpa, gpa_fhdo_offset_time=(1 / 0.2 / 3.1)) samplingPeriod = self.expt.getSamplingRate() bw = 1 / samplingPeriod acqTime = nPoints / bw # us self.mapVals['acqTime'] = acqTime*1e-3 # ms self.mapVals['bw'] = bw # MHz createSequence() if self.floDict2Exp(): print("Sequence waveforms loaded successfully") pass else: print("ERROR: sequence waveforms out of hardware bounds") return False if not plotSeq: # Run the experiment and get data rxd, msgs = self.expt.run() # Decimate the signal dataFull = self.decimate(rxd['rx%i' % rxChannel], nScans) # Average data data = np.average(np.reshape(dataFull, (nScans, -1)), axis=0) self.mapVals['data'] = data # Save data to sweep plot (single point) self.mapVals['sampledPoint'] = data[0] self.expt.__del__() return True
[docs] def sequenceAnalysis(self, obj=''): def getFHWM(s,f_vector,bw): target = np.max(s) / 2 p0 = np.argmax(s) f0 = f_vector[p0] s1 = np.abs(s[0:p0]-target) f1 = f_vector[np.argmin(s1)] s2 = np.abs(s[p0::]-target) f2 = f_vector[np.argmin(s2)+p0] return f2-f1 # Signal and spectrum from 'fir' and decimation signal = self.mapVals['data'] bw = self.mapVals['bw']*1e3 # kHz nPoints = self.mapVals['nPoints'] deadTime = self.mapVals['deadTime']*1e-3 # ms rfExTime = self.mapVals['rfExTime']*1e-3 # ms tVector = np.linspace(rfExTime/2 + deadTime + 0.5/bw, rfExTime/2 + deadTime + (nPoints-0.5)/bw, nPoints) fVector = np.linspace(-bw/2, bw/2, nPoints) spectrum = np.abs(np.fft.ifftshift(np.fft.ifftn(np.fft.ifftshift(signal)))) fitedLarmor=self.mapVals['larmorFreq'] + fVector[np.argmax(np.abs(spectrum))] * 1e-3 #MHz hw.larmorFreq=fitedLarmor fwhm=getFHWM(spectrum, fVector, bw) dB0=fwhm*1e6/hw.larmorFreq for sequence in self.sequence_list.values(): if 'larmorFreq' in sequence.mapVals: sequence.mapVals['larmorFreq'] = hw.larmorFreq # Get the central frequency print('Larmor frequency: %1.5f MHz' % fitedLarmor) print('FHWM: %1.5f kHz' % fwhm) print('dB0/B0: %1.5f ppm' % dB0) self.mapVals['signalVStime'] = [tVector, signal] self.mapVals['spectrum'] = [fVector, spectrum] # Add time signal to the layout result1 = {'widget': 'curve', 'xData': tVector, 'yData': [np.abs(signal), np.real(signal), np.imag(signal)], 'xLabel': 'Time (ms)', 'yLabel': 'Signal amplitude (mV)', 'title': 'Signal vs time', 'legend': ['abs', 'real', 'imag'], 'row': 0, 'col': 0} # Add frequency spectrum to the layout result2 = {'widget': 'curve', 'xData': fVector, 'yData': [spectrum], 'xLabel': 'Frequency (kHz)', 'yLabel': 'Spectrum amplitude (a.u.)', 'title': 'Spectrum', 'legend': [''], 'row': 1, 'col': 0} # create self.out to run in iterative mode self.output = [result1, result2] self.saveRawData() return self.output
if __name__=='__main__': seq = FID() seq.sequenceRun() seq.sequenceAnalysis(obj='Standalone')