| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 | #!/usr/bin/env python3# -*- coding: UTF-8 -*-#from scipy.special import gamma, binomimport numpy as npimport matplotlib.pyplot as pltimport scipy.sparse as sparsefrom scipy.sparse.linalg import eigshfrom numpy.linalg import eigfrom mpmath import mp, mpfmp.dps = 2000voxel_num = 5phase_range = np.pi/2 *0.0phase_init = np.pi/2  #(0.0)U_points = voxel_num * 3000noise_ratio = 0.0*(1.2e-16) #(1.2e-16) #1e8total_periods=10#DO NOT CHANGE to fit T2s_scale autoscalerf_samples_per_period = 20# max polynomial order equals  rf_samples_per_period * total_periods # B0=1.5T freq=64Mhz, period = 15.6 nsperiod = (10.0) #msomega = 2.0*np.pi/period#T2s_scale = 0.01 #ms # need to be 10msT2s_scale = total_periods*period/rf_samples_per_period/voxel_num*8 #ms # need to be 10msT2s_min = T2s_scale/20.0 #mstotal_steps = rf_samples_per_period*total_periodsif total_steps % 2 != 0: total_steps -= 1time_steps = np.array(mp.linspace((0), (period*total_periods), total_steps))tmp = [np.random.rand()*0.0+(1.0) for n in range(voxel_num)]voxel_amplitudes = np.array(tmp)tmp = [np.random.rand() for n in range(voxel_num)]voxel_T2s_decay = np.sort(np.array(tmp))*(T2s_scale-2*T2s_min) + T2s_minvoxel_all = np.append(voxel_amplitudes,voxel_T2s_decay/T2s_scale)if voxel_num == 5:#    voxel_all = np.array([mpf(0.2),(0.6),(0.02),(0.1)])    voxel_all = np.array([(0.822628),(0.691376),(0.282906),(0.226013),(0.90703),(0.144985),(0.228563),(0.340353),(0.462462),(0.720518)])    #voxel_all = np.array([(0.592606),(0.135168),(0.365712),(0.667536),(0.437378),(0.918822),(0.943879),(0.590338),(0.685997),(0.658839)])    voxel_amplitudes = voxel_all[:voxel_num]    voxel_T2s_decay = voxel_all[voxel_num:]*T2s_scale# a_i = np.array([(0.3),(0.1),(0.15),(0.1)])# d_i = np.array([(0.7),(0.9),(0.2),(0.67)])# voxel_num = len(a_i)voxel_phases = np.array(np.linspace(0,phase_range, voxel_num))# if len(voxel_amplitudes) != len(voxel_phases):#     print("ERROR! Size of amplitude and phase arrays do not match!")#     raiseampl = []def gen_rf_signal(time):    '''Generates demodulated signal at radio frequence using voxels    amplitudes, T2s decays, and phases.    '''    tmp = [mpf(0.0) for n in range(len(time))]    mag_sin = np.array(tmp)    mag_cos = np.array(tmp)        for t in range(len(time)):        for i in range(voxel_num):            # mag_sin[t] += a_i[i]*(            #     (d_i[i] + np.random.rand()*noise_ratio)**time[t]            # )            amp = voxel_amplitudes[i] * (                mp.exp(-time[t]/voxel_T2s_decay[i])                ) + ( 0.0                      #     + np.random.rand()*noise_ratio                        )            # if t == 0:                #print("a_{:d}".format(i),float(voxel_amplitudes[i]* np.sin(voxel_phases[i] + phase_init)))                #print("d_{:d}".format(i),float( np.exp(-(period/rf_samples_per_period)/voxel_T2s_decay[i]) ))            mag_sin[t] += amp * np.sin((voxel_phases[i] + phase_init))            mag_cos[t] += amp * np.cos((voxel_phases[i] + phase_init))        mag_sin[t] *= (1 + (np.random.rand()-0.5)*noise_ratio)        #mag_cos[t] += np.random.rand()*noise_ratio    return mag_sin, mag_cosdef factorial(n):    return mp.gamma(n+1)def binom(n,k):    return factorial(n)/(factorial(k)*factorial(n-k))def K ( i, j):    polyL = L[i] #precomputed shiftedLegendre(i)    return polyL.coeffs[-j-1]def GetU (lambdas):    n_max = len(lambdas)    P = np.ones((n_max+1,U_points))    x = np.linspace(0,1, U_points)    P[1] = 2*x-1    for n in range(1,n_max):        P[n+1] = ((2*n+1)/(n+1)) * (2*x-1) * P[n]  - (n/(n+1))*P[n-1]    U = np.zeros(U_points)    for i in range (len(lambdas)):        # if i%10 == 0: print(i)        U += lambdas[i]*P[i]*np.sqrt(2*i+1)        #polyL = L[i] #shiftedLegendre(i)        #U += lambdas[i]*polyL(x)    return Udef GetLambda(mag_rf):    M_cutoff = len(mag_rf)    all_lambda = []    for i in range(M_cutoff):        lambd = mpf(0.0)        for j in range(i+1):            lambd += K(i,j)*mpf(mag_rf[j])#            print("K({:d},{:d}) =".format(i,j), float(K(i,j)))        all_lambda.append(float(lambd))    # tmp = [mpf(0.0) for n in range(M_cutoff)]    # all_lambda = np.array(tmp)    # all_lambda[10] = mpf(1.0)    return all_lambdadef GetAbsLastLambda(mag_rf):    M_cutoff = len(mag_rf)    all_lambda = []    i = M_cutoff - 1    lambd = mpf(0.0)    for j in range(i+1):        lambd += K(i,j)*mpf(mag_rf[j])    #    print("K({:d},{:d}) =".format(i,j), float(K(i,j)))    all_lambda.append(float(lambd))        # tmp = [mpf(0.0) for n in range(M_cutoff)]    # all_lambda = np.array(tmp)    # all_lambda[10] = mpf(1.0)    return np.abs(all_lambda[0])def shiftedLegendre(n):    coeffs = []    for k in range(n+1):        val = mpf(-1)**n * binom(mpf(n),mpf(k)) * binom(n+k,k) * (-1)**k        coeffs.insert(0,val*mp.sqrt(2*n+1))    return np.poly1d(coeffs)def GetGnk(c,n,k):    Gnk = mpf(0.0)    for m in range(k+1):        Gnk+=(-1)**m * binom(mpf(k),mpf(m)) * c[n+m]    return Gnkdef GetGnkSum(c):    total = 0    N = len(c)    for n in range(2):        for k in range (N-n-2,N-n):            Gnk = float(GetGnk(c , n, k))            if Gnk <0:                total += Gnk    return totaldef FixGnk(mag_sin):    total = GetGnkSum(mag_sin)    print(total)    def mat1mp (mag_sin):    N = len(mag_sin)    NN = int((N-1)/2)    tmp = np.array([mpf(0.0) for n in range((NN+1)**2)])    tmp2 = np.reshape(tmp,( NN+1 , NN+1 ))    mat = mp.matrix(tmp2)    # mat = np.zeros(( NN+1 , NN+1 ))    for i in range(NN+1):        for j in range(NN+1):            mat[i,j] = mag_sin[i+j+1]    # print(mat)    return matdef mat1 (mag_sin):    N = len(mag_sin)    NN = int((N-1)/2)    mat = np.zeros(( NN+1 , NN+1 ))    for i in range(NN+1):        for j in range(NN+1):            mat[i,j] = mag_sin[i+j+1]    # print(mat)    return matdef mat2 (mag_sin):    N = len(mag_sin)    NN = int((N-1)/2)    mat = np.zeros(( NN+1 , NN+1 ))    for i in range(NN+1):        for j in range(NN+1):            mat[i,j] = mag_sin[i+j] - mag_sin[i+j+1]    return matdef fitness(corrector):    mag_sin = mag_sin_0*(1 + mpf(1.1)*(corrector-0.5)*noise_ratio)    res = GetAbsLastLambda(mag_sin)    global globi    globi = globi + 1        if globi % 100 == 0: print("REsult", res)    return resmag_sin_0, mag_cos_0 = gen_rf_signal(time_steps)mag_sin = np.copy(mag_sin_0)mag_cos = np.copy(mag_cos_0)L = [] # Shifted Legendre polinomialsfor i in range(len(mag_sin)):    polyL = shiftedLegendre(i)    L += [polyL]globi = 1# import time# time1 = time.time()# corr = np.zeros(len(mag_sin))# fitness(corr)# from scipy.optimize import minimize# # = minimize(fitness,corr,method='L-BFGS-B')# v = minimize(fitness,corr,method='TNC',options={'disp': False, 'minfev': 0, 'scale': None, 'rescale': -1, 'offset': None, 'gtol': -1, 'eps': 1e-08, 'eta': -1, 'maxiter': None, 'maxCGit': -1, 'mesg_num': None, 'ftol': -1, 'xtol': -1, 'stepmx': 0, 'accuracy': 0})# # from scipy.optimize import differential_evolution# # bounds = []# # for i in range(len(mag_sin)):# #     bounds.append((0,1))# # v = differential_evolution(fitness,bounds)# fitness(v.x)# print(v.fun, "at", v.x)# time2 = time.time()# print( 'it took %0.5f s' % ((time2-time1)))print("N = ",len(mag_sin))print("Noise = ", noise_ratio )# print("c_n =",["%0.8f"%(x) for x in mag_sin])# print("mat1 =",mat1(mag_sin))# print("mat2 =",mat2(mag_sin))#print( 'eigsh took %0.5f s' % ((time2-time1)))#print("eigsh1 = ",v1,"eigsh2 = ",v2)# v1f = eig(mat1(mag_sin))# v2f = eig(mat2(mag_sin))# print("eig1 = ",np.sort(v1f[0]))# print("eig2 = ",np.sort(v2f[0]))# v = eigsh(mat2(mag_sin), k=6, return_eigenvectors=False, which='LA')# print(v)# N = len(mag_sin)# print("N = ", N)# for n in range(2):#     for k in range (N-n-2,N-n):#         Gnk = float(GetGnk(mag_sin, n, k))#         if Gnk <0:#             print("G",n,k," = ", Gnk)        #FixGnk(mag_sin)sign = ""# for i in range(voxel_num):#     if i%5 == 0:#         sign+="\n"#     sign = sign + '{:3.2g}'.format(float(a_i[i]))+"/"+'{:3.2g}'.format(float(d_i[i]))+", "# # #    print(mp.exp(-1.0/voxel_T2s_decay[i]))                plt.plot(mag_sin, ls=' ', marker='o')plt.title("Signal to restore amp/decay_T:"+sign)plt.savefig("signal.pdf")plt.clf()recL = []    x = np.linspace(0,1, U_points)# polyL_val = np.array([float(L[-1](x[n])) for n in range(U_points)])# plt.plot(x,polyL_val)# plt.title("Legendre polynom of order "+str(len(L)))# plt.savefig("polyL.pdf")# plt.clf()#print("Before lambda.")import timetime1 = time.time()lambdas = GetLambda(mag_sin)time2 = time.time()print( 'GetLambda took %0.5f s' % ((time2-time1)))print((lambdas))U = GetU(lambdas)sign ="" for i in range(voxel_num):    sign+="{:4.3g}, ".format(float( mp.exp(-(period/rf_samples_per_period)/voxel_T2s_decay[i]) ))#print(sign)x = np.linspace(0,1, U_points)mag_x = np.linspace(0,1, len(mag_sin))import matplotlib as matplotlibmatplotlib.rcParams.update({'font.size': 28})plt.figure(figsize=(30, 20))plt.plot(x,U, lw=0.2)plt.title(r"$\sum^M \lambda_i L_i(x)$", y=1.02)plt.xlim(0,1)plt.xlabel(sign, fontsize=28)plt.savefig("plt.pdf")plt.clf()# rms = np.sqrt(np.mean(U**2))/np.max(U)# #print(rms)# status = "OK"# if rms < 0.2: status = "BAD"# print("rms =", rms, status)
 |