# -*- coding: utf-8 -*-
"""
Created on Fri Sep  5 16:31:21 2025

@author: AKourgli
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.constants import speed_of_light

# Paramètres de base
freq = 2.4e9  # Fréquence en Hz
c = speed_of_light
wavelength = c / freq
dipole_length = wavelength / 2

print(f"Fréquence: {freq/1e6} MHz")
print(f"Longueur d'onde: {wavelength:.3f} m")
print(f"Longueur du dipôle: {dipole_length:.3f} m")

def dipole_pattern(theta):
    """Calcul du diagramme de rayonnement d'un dipôle demi-onde"""
    beta = 2 * np.pi / wavelength
    L = dipole_length
    return (np.cos((beta * L / 2) * np.cos(theta)) - np.cos(beta * L / 2)) / np.sin(theta)

# Calcul pour différentes directions
theta = np.linspace(0.001, 2*np.pi, 360)  # Éviter theta=0 pour division par zéro
pattern = dipole_pattern(theta)

# Normalisation
pattern = np.abs(pattern)
pattern_db = 10 * np.log10(pattern / np.max(pattern))

# Tracé du diagramme
plt.figure(figsize=(8, 8))
ax = plt.subplot(111, projection='polar')
ax.plot(theta, pattern_db)
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_rmin(-30)
ax.set_rmax(0)
ax.set_title("Diagramme de rayonnement d'un dipôle demi-onde")
plt.show()

def dipole_impedance(freq, length, radius):
    """Calcul approximatif de l'impédance d'un dipôle"""
    # Formule simplifiée pour l'impédance d'entrée
    k = 2 * np.pi * freq / c
    a = radius
    R = 20 * (k * length)**2
    X = 120 * (np.log(length / (2 * a)) - 1) * np.tan(k * length / 2)
    return R + 1j * X

def calculate_swr(Z_ant, Z0=50):
    """Calcul du Taux d'Ondes Stationnaires"""
    gamma = (Z_ant - Z0) / (Z_ant + Z0)
    gamma_magnitude = abs(gamma)
    
    # Éviter la division par zéro
    if gamma_magnitude >= 0.999:  # Si le coefficient de réflexion est très proche de 1
        return float('inf')  # TOS infini (mauvaise adaptation totale)
    
    swr = (1 + gamma_magnitude) / (1 - gamma_magnitude)
    return swr

# Calcul pour notre dipôle
Z_ant = dipole_impedance(freq, dipole_length, 0.0001)
swr = calculate_swr(Z_ant)

print(f"Impédance de l'antenne: {Z_ant:.2f} Ω")
print(f"TOS: {swr:.2f}")

# Étude paramétrique
lengths = np.linspace(0.4 * wavelength, 0.6 * wavelength, 50)
swr_values = []
impedances = []

for L in lengths:
    Z = dipole_impedance(freq, L, 0.0001)
    swr = calculate_swr(Z)
    swr_values.append(swr)
    impedances.append(Z)

# Tracé des résultats
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(lengths/wavelength, swr_values)
plt.xlabel('Longueur (en λ)')
plt.ylabel('TOS')
plt.grid(True)
plt.title('Évolution du TOS en fonction de la longueur')

plt.subplot(1, 2, 2)
impedances = np.array(impedances)
plt.plot(lengths/wavelength, np.real(impedances), label='Partie réelle')
plt.plot(lengths/wavelength, np.imag(impedances), label='Partie imaginaire')
plt.xlabel('Longueur (en λ)')
plt.ylabel('Impédance (Ω)')
plt.legend()
plt.grid(True)
plt.title('Évolution de l\'impédance en fonction de la longueur')

plt.tight_layout()
plt.show()

# Simulation d'une antenne monopole quart d'onde
def monopole_pattern(theta):
    """Diagramme de rayonnement d'un monopole quart d'onde"""
    # Pattern similaire mais dans l'hémisphère supérieur seulement
    pattern = dipole_pattern(theta)
    pattern = np.where(theta > np.pi/2, 0, pattern)  # Pas de rayonnement en dessous de l'horizon
    return pattern

# Calcul pour différentes directions
monopole_pattern_values = monopole_pattern(theta)

# Normalisation
monopole_pattern_values = np.abs(monopole_pattern_values)
monopole_pattern_db = 10 * np.log10(monopole_pattern_values / np.max(monopole_pattern_values))

# Tracé du diagramme
plt.figure(figsize=(8, 8))
ax = plt.subplot(111, projection='polar')
ax.plot(theta, monopole_pattern_db)
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_rmin(-30)
ax.set_rmax(0)
ax.set_title("Diagramme de rayonnement d'un monopole quart d'onde")
plt.show()

# Calcul de l'impédance d'un monopole quart d'onde
monopole_length = wavelength / 4
Z_monopole = dipole_impedance(freq, monopole_length, 0.0001) / 2  # Impédance environ moitié de celle d'un dipôle
swr_monopole = calculate_swr(Z_monopole)

print(f"Impédance du monopole: {Z_monopole:.2f} Ω")
print(f"TOS du monopole: {swr_monopole:.2f}")