<!-- canonical: https://jmrplens.github.io/phonometry/es/guides/rotorcraft-noise/ -->
Source: https://jmrplens.github.io/phonometry/es/guides/rotorcraft-noise/

El ruido de los helicópteros es muy directivo, así que el método de **ECAC
Doc 32** describe la fuente con un **hemisferio de ruido**: niveles de presión
acústica en bandas de 1/3 de octava sobre una malla esférica de azimut `φ` y ángulo
polar `θ`, definidos a una distancia de referencia fija de **60 m** en condiciones
atmosféricas de referencia de la ICAO. Situar esa fuente en un receptor añade el
ajuste de propagación `ΔLp = ΔLs + ΔLa + ΔLg`.

## El hemisferio de ruido

Un `RotorcraftHemisphere` contiene los niveles de banda sobre la malla
azimut/polar. `hemisphere_source_level` lee el nivel en una dirección de emisión
arbitraria: primero rellena los huecos de la malla desde los bins llenos
angularmente más cercanos (Ec. 14/15, con caché) y después interpola de forma
bilineal en el dominio de energía sobre los cuatro bins vecinos (Ec. 13), de modo que las
celdas parcialmente medidas se mantienen continuas con sus esquinas medidas.

```python
from phonometry import aircraft

h = aircraft.RotorcraftHemisphere(frequencies=freqs, azimuth=phi, polar=theta, levels=levels)
lv = aircraft.hemisphere_source_level(h, 0.0, 90.0)   # nivel de fuente por banda a 60 m
h.plot()                                          # directividad proa-popa
```

## Ajustes de propagación

El nivel del hemisferio a 60 m se lleva al receptor con tres ajustes (§A.4):
`spherical_spreading_adjustment` (`ΔLs = −20·log10(r/60)`, Ec. 24),
`atmospheric_adjustment` (`ΔLa = −α(f)·(r − 60)` con el coeficiente de
ISO 9613-1, Ec. 26/27) y `ground_effect_adjustment` (interferencia directo/
reflejado sobre un plano de impedancia, Chien-Soroka Ec. 28-35, con la impedancia
de Delany-Bazley y las clases de resistividad de flujo CNOSSOS `"A"`-`"H"`).

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import aircraft

freqs = 1000.0 * 10.0 ** (np.arange(-13, 11) / 10.0)   # tercios 50 Hz-10 kHz
hs, hr, dp = 150.0, 1.5, 500.0                          # geometría de sobrevuelo
grass = aircraft.ground_effect_adjustment(freqs, hs, hr, dp, flow_resistivity="D")
asphalt = aircraft.ground_effect_adjustment(freqs, hs, hr, dp, flow_resistivity="G")

fig, ax = plt.subplots()
ax.axhline(0.0, color="0.5", linewidth=1.0)
ax.semilogx(freqs, asphalt, marker="o", markersize=3,
            label="Duro (asfalto/hormigón, clase G)")
ax.semilogx(freqs, grass, marker="s", markersize=3,
            label="Blando (hierba/pasto, clase D)")
ax.set(xlabel="Frecuencia central de banda de tercio de octava [Hz]",
       ylabel="Ajuste por efecto de suelo ΔLg [dB]",
       title="Efecto de suelo de rotorcraft (ECAC Doc 32, Chien-Soroka)")
ax.grid(True, which="both", alpha=0.3)
ax.legend()
plt.show()
```

</details>

```python

from phonometry import aircraft

freqs = 1000.0 * 10.0 ** (np.arange(-13, 11) / 10.0)   # tercios 50 Hz-10 kHz
r = 500.0
recibido = (lv
            + aircraft.spherical_spreading_adjustment(r)
            + aircraft.atmospheric_adjustment(freqs, r)
            + aircraft.ground_effect_adjustment(freqs, 150.0, 1.5, 500.0, flow_resistivity="D"))
```

La base de datos estándar está registrada a 60 m, el valor por defecto. Si un
hemisferio usa otra distancia polar (`h.distance`, p. ej. anillos de hover a
70 m), pásala a los dos ajustes dependientes de la distancia como
`reference_distance=h.distance`.

## Condiciones de vuelo: interpolar entre hemisferios

Una base de datos registra un hemisferio por condición de vuelo (velocidad
aerodinámica `V`, ángulo de trayectoria `γ`). Las condiciones reales rara vez
coinciden con una medida, así que la guía NORAH2 interpola (Ec. 3-10): ambos
ejes se normalizan por sus rangos en la base de datos (con el factor empírico
`Ffc = 2` sobre el ángulo de trayectoria), una triangulación de Delaunay cubre
las condiciones normalizadas, y una consulta dentro de la envolvente convexa
mezcla su triángulo envolvente con pesos inversos a la distancia en el dominio
de energía. Fuera de la envolvente se adopta la condición más cercana sin
mezclar, que es también el comportamiento que ECAC Doc 32, 1.ª ed. prescribe
para toda su envolvente (aún no define interpolación).

```python
from phonometry import aircraft

speeds = [50.0, 70.0, 60.0]                # un hemisferio por condición
angles = [0.0, 0.0, 10.0]                  # ángulos de trayectoria, grados
weights = aircraft.flight_condition_weights(speeds, angles, 60.0, 2.5)
lv = aircraft.interpolated_source_level(
    [h_50_nivel, h_70_nivel, h_60_ascenso], speeds, angles,
    60.0, 2.5, 0.0, 90.0)                  # nivel mezclado por banda
```

La velocidad aerodinámica, no la de suelo, selecciona el hemisferio; los pesos
son invariantes a las unidades mientras la consulta use las de la base de
datos. Puede pasarse una tabla de triangulación de la base de datos como
`triangles` (la base NORAH incluye una por tipo; las tablas incluidas
triangulan el plano `(V, γ)` sin normalizar, así que pasarlas reproduce la
implementación de referencia bin a bin). Los miembros de clase con rotor
especular sustituyen `h.mirrored()` (Ec. 2, `φ → −φ`) y los desplazamientos por
nivel de certificación entran como `level_offset`.

## Cinemática de la trayectoria

`flight_path_kinematics` deriva de una trayectoria con marcas de tiempo, por
diferencias finitas centradas, todo lo que necesita el evento (Ec. 16-21 /
Doc 32 Ec. 8-10): velocidad respecto al suelo, velocidad aerodinámica (sin
viento), rumbo, curvatura, ángulo de alabeo `Φ = atan(K·Vg²/g)` y ángulo de
trayectoria `γ = atan(ΔZ/ΔS)`. La guía recomienda suavizar las trazas radar
(p. ej. remuestreo con splines a cadencia de 0,5 s) antes de derivar.

```python
kin = aircraft.flight_path_kinematics(times, positions)   # posiciones (N, 3), m
kin.airspeed, kin.path_angle          # seleccionan el hemisferio por punto
kin.bank_angle                        # inclina el hemisferio en virajes
kin.plot()                            # perfiles de velocidad y ángulos
```

## El evento único: SEL, LASmax y EPNL

`rotorcraft_event_level` ejecuta toda la cadena para un sobrevuelo en un
receptor: por punto de trayectoria la condición de vuelo selecciona (o mezcla)
los hemisferios, los ángulos de emisión direccionan el nivel de fuente (el
marco se orienta con el rumbo y se inclina con el alabeo en virajes; la actitud
de cabeceo está implícita en los hemisferios), y el historial recibido en
tercios de octava se expresa en tiempo registrado `tr = te + r/c` (Ec. 22,
`c = 346.1 m/s`) y se integra: `LASmax`, `SEL` sobre el historial completo y
sobre la ventana de certificación de 10 dB de caída (Doc 32 Ec. 27), y `EPNL`
según ICAO Anexo 16 (Doc 32 Ec. 28).

```python
res = aircraft.rotorcraft_event_level(
    hemispheres, speeds, angles,      # la base de datos
    times, positions,                 # la trayectoria (m, z hacia arriba)
    receiver=(120.0, 0.0),            # posición en tierra del micrófono
    flow_resistivity="D")             # emplazamiento de hierba
res.la_max, res.sel, res.epnl         # LASmax, SEL, EPNL
res.plot()                            # el historial temporal LA(t)
```

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import aircraft

# Hemisferio sintético tipo helicóptero en la malla estándar de 31 bandas y 10°.
freqs = 1000.0 * 10.0 ** (np.arange(-20, 11) / 10.0)   # tercios 10 Hz-10 kHz
az = np.arange(-90.0, 91.0, 10.0)
po = np.arange(0.0, 181.0, 10.0)
spectrum = 88.0 - 12.0 * np.log10(freqs / 100.0) ** 2   # joroba en baja-media
levels = (spectrum[None, None, :] - 0.045 * np.abs(po - 80.0)[None, :, None]
          - 0.02 * np.abs(az)[:, None, None])
h = aircraft.RotorcraftHemisphere(freqs, az, po, levels)

speed = 30.87                                           # 60 kt, en m/s
t = np.arange(0.0, 130.01, 0.5)
track = np.column_stack([np.zeros_like(t), speed * (t - 65.0),
                         np.full_like(t, 150.0)])
event = aircraft.rotorcraft_event_level(
    [h], [speed], [0.0], t, track, (120.0, 0.0), flow_resistivity="D")
event.plot(language="es")
plt.show()
```

</details>

Los flujos con trazas radar pueden pasar directamente los valores suavizados por
punto de `airspeed`, `path_angle`, `heading` y `bank_angle` en lugar de
derivarlos de las posiciones; cuando se derivan, la trayectoria está en metros
y segundos, así que la base de datos de velocidades debe estar entonces en m/s.

## Contornos en malla de tierra

`rotorcraft_noise_contour` evalúa el mismo evento sobre una malla completa en
una pasada vectorizada por paso de emisión y reduce el historial de cada
receptor a la huella `SEL` (`metric="exposure"`) o `LASmax`
(`metric="maximum"`):

```python

from phonometry import aircraft

res = aircraft.rotorcraft_noise_contour(
    hemispheres, speeds, angles, times, positions,
    x=np.linspace(-2000.0, 2000.0, 81),
    y=np.linspace(-3000.0, 3000.0, 121),
    metric="exposure", flow_resistivity="D")
res.plot()                            # contornos SEL rellenos
```

El suelo puede variar entre receptores sin un modelo de elevación completo:
`flow_resistivity` y `ground_elevation` aceptan un valor por punto de malla
(forma `(len(y), len(x))`), y el modelo de dos rayos de cada receptor usa
entonces sus valores locales.

## Terreno: el plano medio del suelo y el apantallamiento

Doc 32, 1.ª ed., supone terreno plano; su guía añade la maquinaria para
emplazamientos reales. Una sección vertical variable se representa por su
**plano medio del suelo** (Ec. 36-40), la recta de mínimos cuadrados a través
de la polilínea del terreno calculada en forma cerrada; la fuente y el
receptor entran en las ecuaciones de suelo plano con sus **alturas
equivalentes**, medidas ortogonalmente a ese plano y con suelo mínimo de
0,1 m. El suelo que cambia de tipo a lo largo del camino promedia su
resistividad de flujo por el logaritmo, ponderada por la longitud de cada
segmento (Ec. 41).

Cuando el terreno bloquea la línea de visión, el sonido sigue el camino
convexo más corto sobre él (la banda elástica de la guía) y cada vértice
tocado es una **arista de difracción**. La atenuación combina la difracción
pura de la diferencia de camino `δ` (Ec. 42-44,
`10·Ch·log10(3 + (40/λ)·C″·δ)`, con tope de 25 dB) con los efectos de suelo
del lado fuente y del lado receptor, cada uno sobre su propio plano medio y
ponderado por la difracción de su camino imagen (Ec. 45-47, el esquema
CNOSSOS-EU que adopta la guía). El efecto de suelo no se evalúa por separado
en ese régimen.

`mean_ground_plane`, `mean_flow_resistivity` y `diffraction_attenuation`
exponen las piezas; `terrain_screening_adjustment` ejecuta la sección
completa:

```python

from phonometry import aircraft

d = [0.0, 150.0, 260.0, 300.0, 340.0, 420.0, 600.0]     # distancias de sección
z = [0.0, 4.0, 48.0, 62.0, 40.0, 8.0, 2.0]              # alturas del terreno
freqs = 1000.0 * 10.0 ** (np.arange(-13, 11) / 10.0)
res = aircraft.terrain_screening_adjustment(
    freqs, source=(0.0, 90.0), receiver=(600.0, 3.2), distances=d, heights=z,
    flow_resistivity="D")
res.screened, res.path_difference      # True, la delta de la banda elástica
res.adjustment                         # por banda, sustituye al ΔLg plano
res.plot()                             # la geometría de la sección
```

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import aircraft

freqs = 1000.0 * 10.0 ** (np.arange(-13, 11) / 10.0)   # tercios 50 Hz-10 kHz
d = np.array([0.0, 150.0, 260.0, 300.0, 340.0, 420.0, 600.0])
z = np.array([0.0, 4.0, 48.0, 62.0, 40.0, 8.0, 2.0])
res = aircraft.terrain_screening_adjustment(
    freqs, (0.0, 90.0), (600.0, 3.2), d, z, flow_resistivity="D")
flat = aircraft.ground_effect_adjustment(freqs, 90.0, 1.2, 600.0,
                                         flow_resistivity="D")

fig, (ax, ax2) = plt.subplots(2, 1, figsize=(9, 7))
res.plot(ax=ax, language="es")
ax2.axhline(0.0, color="0.5", linewidth=1.0)
ax2.semilogx(freqs, flat, ls="--", marker="s", markersize=3,
             label="Suelo plano (sin colina)")
ax2.semilogx(freqs, res.adjustment, marker="o", markersize=3,
             label="Apantallado por la colina (Ec. 45-47)")
ax2.set(xlabel="Frecuencia central de banda de tercio de octava [Hz]",
        ylabel="Ajuste de suelo y apantallamiento [dB]")
ax2.grid(True, which="both", alpha=0.3)
ax2.legend()
plt.show()
```

</details>

El evento y el contorno funcionan sobre emplazamientos reales pasando un
modelo digital de elevaciones: `terrain=(x, y, z)` en el marco de la
trayectoria. Cada par emisión-receptor muestrea entonces su propia sección
vertical con paso `terrain_resolution` (por defecto, el tamaño de celda del
modelo) y la evalúa con la maquinaria anterior; el suelo del receptor sale
del modelo. El coste crece con puntos de trayectoria por puntos de malla, así
que con terreno conviene mantener mallas de contorno moderadas.

```python
res = aircraft.rotorcraft_event_level(
    hemispheres, speeds, angles, times, positions, receiver=(1200.0, 300.0),
    terrain=(tx, ty, tz), flow_resistivity="D")
```

## Validación

Validado contra la Tabla 4 de la guía NORAH2 (las 31 bandas), el ensanchamiento
inverso al cuadrado de forma cerrada, los límites analíticos de suelo rígido y
rasante del efecto de suelo, consultas bilineales fuera de nodo sobre los
hemisferios de referencia de los once tipos de helicóptero, símplices de
interpolación comprobados a mano, cinemática de forma cerrada y la integral
lorentziana `SEL − LASmax` del sobrevuelo, y de extremo a extremo contra los
casos ARP de verificación del prototipo NORAH2: ángulos de emisión a 0,01°,
tiempos retardados a 0,02 s, cada nivel por paso de los eventos sobre suelo
duro a 0,08 dB(A) hasta 18 km, `LASmax` a 0,03 dB, `SEL` a 0,05 dB sobre suelo
duro (0,4 dB sobre suelo blando), la malla de contorno de 187 micrófonos a
0,7 dB en el peor caso, `PNLTM` a 0,1 dB y `EPNL` a aproximadamente 1,3 dB (la
política de noys del prototipo por debajo del suelo de la tabla difiere de la
ley publicada del Anexo 16). Queda una divergencia documentada: a gran distancia sobre suelo
blando el prototipo amortigua la interferencia coherente de dos rayos de la
Ec. 30 de la guía hacia la suma incoherente (hasta 4,9 dB en pasos individuales
de bajo nivel más allá de 7 km); ni Doc 32 ni la guía contienen tal término, y
esta implementación sigue las ecuaciones publicadas.

La maquinaria de terreno está anclada en forma cerrada: el plano medio del
suelo es exacto en perfiles lineales y simétricos, una sección plana
reproduce el modelo de suelo plano a precisión de máquina y un plano
inclinado su rotación analítica, la resistividad media logarítmica recupera
la media geométrica, la difracción rasante da el clásico `10·log10(3)`, y
una colina comprobada a mano fija la diferencia de camino de la banda
elástica. El tratamiento del suelo por receptor valida de extremo a extremo
contra el Case 3 ARP del prototipo (187 micrófonos, cada uno sobre su propia
elevación: cada nivel por paso a 0,08 dB(A), `SEL`/`LASmax` a 0,05 dB, la
malla de contorno a 0,15 dB) y la malla de suelo mixto del Case 2 se
reproduce en una sola llamada con resistividad por receptor. La versión
pública del prototipo no incluye un caso de apantallamiento reconstruible
(el marco de su modelo de terreno no pudo fijarse a las salidas publicadas),
así que la cadena de difracción se ancla en las formas cerradas y en su
filiación CNOSSOS-EU.

## Qué cubre esta guía

**Cubierto.** El método del hemisferio de ECAC Doc 32 y la guía a nivel de
ecuación NORAH2 de EASA (§A.3-A.5): el hemisferio de ruido y su consulta
bilineal (`RotorcraftHemisphere`, `hemisphere_source_level`), los tres
ajustes de propagación (`spherical_spreading_adjustment`,
`atmospheric_adjustment`, `ground_effect_adjustment`, el modelo de
Chien-Soroka con la impedancia de Delany-Bazley y las clases de resistividad
de flujo CNOSSOS), la interpolación entre condiciones de vuelo
(`flight_condition_weights`, `interpolated_source_level`), la cinemática de
la trayectoria (`flight_path_kinematics`), el SEL, LASmax y EPNL de evento
único (`rotorcraft_event_level`), los contornos en malla de tierra
(`rotorcraft_noise_contour`) y la cadena de plano medio del suelo y
apantallamiento por terreno (`mean_ground_plane`, `mean_flow_resistivity`,
`diffraction_attenuation`, `terrain_screening_adjustment`). Validado contra
la Tabla 4 de la guía NORAH2, límites geométricos y rasantes en forma cerrada,
y de extremo a extremo contra los casos de verificación ARP del prototipo
NORAH2.

**No cubierto.** El tratamiento de fuente en hover, ralentí y rodaje (guía
§A.3.5) queda fuera de la implementación: el modelo de fuente por hemisferio
asume un sobrevuelo, no un helicóptero estacionario o en ralentí en tierra.

## Véase también

- Referencia de la API: [`aircraft.rotorcraft_noise`](/phonometry/es/reference/api/aeroacoustics/rotorcraft-noise/).
