Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sourcery refactored main branch #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 32 additions & 34 deletions jupyter notebooks/CommpyTest_BERvsEbN0_wPulseShaping.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,38 +68,38 @@ def GrayMapping(M, constType):

L = int(np.sqrt(M)-1)
bitsSymb = int(np.log2(M))

code = GrayCode(bitsSymb)
a = list(code.generate_gray())

Comment on lines -71 to +74
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function GrayMapping refactored with the following changes:

if constType == 'qam':
PAM = np.arange(-L, L+1, 2)
PAM = np.array([PAM])

# generate complex square M-QAM constellation
const = repmat(PAM, L+1, 1) + 1j*repmat(np.flip(PAM.T,0), 1, L+1)
const = const.T

for ind in np.arange(1,L+1,2):
const[ind] = np.flip(const[ind],0)

elif constType == 'psk':
pskPhases = np.arange(0,2*np.pi,2*np.pi/M)

# generate complex M-PSK constellation
const = np.exp(1j*pskPhases)

const = const.reshape(M,1)
const_ = np.zeros((M,2),dtype=complex)


for ind in range(0,M):

for ind in range(M):
const_[ind,0] = const[ind,0] # complex constellation symbol
const_[ind,1] = int(a[ind],2) # mapped bit sequence (as integer decimal)

# sort complex symbols column according to their mapped bit sequence (as integer decimal)
const = const_[const_[:,1].real.argsort()]

return const


Expand All @@ -121,12 +121,10 @@ def modulateGray(bits, M, constType):
def demodulateGray(symb, M ,constType):

const = GrayMapping(M, constType)

hdDecision_vec = np.vectorize(hdDecision, excluded = [1])
index_list = hdDecision_vec(symb, const[:,0])
demod_bits = dec2bitarray(index_list, int(np.log2(M)))

return demod_bits

hdDecision_vec = np.vectorize(hdDecision, excluded = [1])
index_list = hdDecision_vec(symb, const[:,0])
return dec2bitarray(index_list, int(np.log2(M)))
Comment on lines -124 to +127
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function demodulateGray refactored with the following changes:


def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):

Expand Down Expand Up @@ -158,7 +156,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
alpha = 0.05 # Rolloff do filtro RRC
N = 1024 # Número de coeficientes do filtro RRC
EbN0dB = 20

Comment on lines -161 to +159
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 161-320 refactored with the following changes:

# generate random bits
bitsTx = np.random.randint(2, size=3*2**12)

Expand All @@ -176,7 +174,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
# pulse shaping
#pulseFilter = pulseShape('rrc', SpS, N, alpha, Ts)
tindex, rrcFilter = rrcosfilter(N, alpha, Ts, Fa)
sigTx = filterNoDelay(pulseFilter, symbolsUp)
sigTx = filterNoDelay(pulseFilter, symbolsUp)
sigTx = sigTx/np.sqrt(signal_power(sigTx))

# plot eye diagrams
Expand Down Expand Up @@ -211,7 +209,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):

# +
# matched filter
sigRx = filterNoDelay(rrcFilter, sigRx)
sigRx = filterNoDelay(rrcFilter, sigRx)
sigRx = sigRx/SpS

# plot eye diagrams
Expand Down Expand Up @@ -240,7 +238,7 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
BERtheory = theoryBER(M, EbN0dB,'qam')

# print results
print('EbN0: %3.2f dB, EbN0_est: %3.2f dB,\nBERtheory: %3.1e, BER: %3.1e ' %(EbN0dB, EbN0dB_est, BERtheory, BER))
print('EbN0: %3.2f dB, EbN0_est: %3.2f dB,\nBERtheory: %3.1e, BER: %3.1e ' %(EbN0dB, EbN0dB_est, BERtheory, BER))
print('Total of bits counted: ', ERR.size)

# plot constellations
Expand Down Expand Up @@ -268,29 +266,30 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
BER = np.zeros(EbN0dB_.shape)
EbN0dB_est = np.zeros(EbN0dB_.shape)

discard = 100
for indSNR in range(EbN0dB_.size):

EbN0dB = EbN0dB_[indSNR]

# generate random bits
bitsTx = np.random.randint(2, size=3*2**18)

# map bits to constellation symbols
mod = QAMModem(m=M)
symbTx = mod.modulate(bitsTx)
Es = mod.Es;

# Normalize symbols energy to 1
symbTx = symbTx/np.sqrt(Es)

# Aumenta a taxa de amostragem do sinal para SpS amostras/símbolo
symbolsUp = upsample(symbTx, SpS)

# filtro formatador de pulso
tindex, rrcFilter = rrcosfilter(N, alpha, Ts, Fa)
symbolsUp = filterNoDelay(rrcFilter, symbolsUp)
symbolsUp = filterNoDelay(rrcFilter, symbolsUp)
symbolsUp = symbolsUp/np.sqrt(signal_power(symbolsUp))

# AWGN channel
snrdB = EbN0dB + 10*np.log10(np.log2(M))
noiseVar = 1/(10**(snrdB/10))
Expand All @@ -300,24 +299,23 @@ def pulseShape(pulseType, SpS=2, N=1024, alpha=0.1, Ts=1):
noise = 1/np.sqrt(2)*noise

symbRx = symbolsUp + noise

# filtro casado
symbRx = filterNoDelay(rrcFilter, symbRx)
symbRx = filterNoDelay(rrcFilter, symbRx)
symbRx = symbRx/SpS

# Decimação para uma amostra por símbolo
symbRx = symbRx[0::SpS]

# Demodulate received symbols
bitsRx = mod.demodulate(np.sqrt(Es)*symbRx, demod_type = 'hard')
discard = 100
bitsRx = mod.demodulate(np.sqrt(Es)*symbRx, demod_type = 'hard')
numBits = bitsTx.size;

# BER calculation, EbN0 estimation
ERR = np.logical_xor(bitsRx[discard:numBits-discard], bitsTx[discard:numBits-discard])
BER[indSNR] = ERR.sum()/ERR.size
EbN0dB_est[indSNR] = 10*np.log10(1/(signal_power(symbRx-symbTx)*np.log2(M)))

print('EbN0: %3.2f dB, EbN0_est: %3.2f dB, BER: %3.1e ' %(EbN0dB, EbN0dB_est[indSNR], BER[indSNR]))


Expand Down
4 changes: 2 additions & 2 deletions jupyter notebooks/Detecção de sinais ópticos e ruído.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@
σ2_s = 2*q*(Ip + Id)*B # variância
μ = 0 # média

σ = np.sqrt(σ2_s)
σ = np.sqrt(σ2_s)
Is = normal(μ, σ, Namostras)

# plotas as primeiras 1000 amostras
plt.plot(Is[0:1000],linewidth = 0.8);
plt.plot(Is[:1000], linewidth = 0.8);
Comment on lines -148 to +152
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 148-152 refactored with the following changes:

plt.xlim(0,1000)
plt.ylabel('Is')
plt.xlabel('amostra')
Expand Down
4 changes: 1 addition & 3 deletions jupyter notebooks/Geração de sinais ópticos.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,7 @@ def mzm(Ai, Vπ, u, Vb):
:return Ao: amplitude da portadora modulada
"""
π = np.pi
Ao = Ai*np.cos(0.5/Vπ*(u+Vb)*π)

return Ao
return Ai*np.cos(0.5/Vπ*(u+Vb)*π)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function mzm refactored with the following changes:



# ### Transmitindo informação na intensidade (potência) da portadora óptica
Expand Down
28 changes: 12 additions & 16 deletions jupyter notebooks/Sistemas coerentes.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,17 +298,15 @@ def hybrid_2x4_90(E1, E2):

M = Matrix([[C_3dB, zeros(2)],
[zeros(2), C_3dB]])

U = Matrix([[1, 0, 0, 0],
[0, 0, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, j]])

Ei = Matrix([[E1],[0],[0],[E2]]) # vetor 4x1

Eo = M*U*M*Ei

return Eo

return M*U*M*Ei
Comment on lines -301 to +309
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function hybrid_2x4_90 refactored with the following changes:


# fotodetector balanceado
def bpd(E1, E2, R=1):
Expand Down Expand Up @@ -406,19 +404,17 @@ def hybrid_2x4_90deg(E1, E2):
:return: hybrid outputs
'''
assert E1.size == E2.size, 'E1 and E2 need to have the same size'

# optical hybrid transfer matrix
T = np.array([[ 1/2, 1j/2, 1j/2, -1/2],
[ 1j/2, -1/2, 1/2, 1j/2],
[ 1j/2, 1/2, -1j/2, -1/2],
[-1/2, 1j/2, -1/2, 1j/2]])

Ei = np.array([E1, np.zeros((E1.size,)),
np.zeros((E1.size,)), E2])

Eo = T@Ei

return Eo

return T@Ei
Comment on lines -409 to +417
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function hybrid_2x4_90deg refactored with the following changes:


def coherentReceiver(Es, Elo, Rd=1):
'''
Expand Down Expand Up @@ -447,12 +443,12 @@ def coherentReceiver(Es, Elo, Rd=1):

def phaseNoise(lw, Nsamples, Ts):

σ2 = 2*np.pi*lw*Ts
σ2 = 2*np.pi*lw*Ts
phi = np.zeros(Nsamples)
for ind in range(0, Nsamples-1):

for ind in range(Nsamples-1):
phi[ind+1] = phi[ind] + normal(0, np.sqrt(σ2))

Comment on lines -450 to +451
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function phaseNoise refactored with the following changes:

return phi


Expand Down
Loading