# Guida alla Migrazione MATLAB → Python

Questo documento fornisce una guida dettagliata per completare la conversione dei moduli MATLAB rimanenti.

## Stato Attuale della Conversione

### ✅ Completato

#### Moduli Comuni
- [x] `database.py` - Connessione e query database
- [x] `config.py` - Gestione configurazione e parametri
- [x] `logging_utils.py` - Sistema di logging
- [x] `validators.py` - Validazione dati

#### Modulo RSN
- [x] `rsn/main.py` - Entry point principale
- [x] `rsn/conversion.py` - Conversione dati grezzi
- [x] `rsn/averaging.py` - Media temporale
- [x] `rsn/elaboration.py` - Elaborazione principale
- [x] `rsn/db_write.py` - Scrittura database

#### Modulo Tilt
- [x] `tilt/geometry.py` - Calcoli geometrici e quaternioni
- [x] `tilt/main.py` - Entry point principale (stub)

#### Modulo ATD
- [x] `atd/star_calculation.py` - Calcolo stella per posizionamento
- [x] `atd/main.py` - Entry point principale (stub)

#### Modulo Monitoring
- [x] `monitoring/alerts.py` - Sistema allerte

### ⚠️ Da Completare

#### Modulo RSN
- [ ] `rsn/data_processing.py` - Implementazione completa caricamento dati
- [ ] `rsn/sensors/` - Moduli specifici per ogni tipo di sensore

#### Modulo Tilt
- [ ] `tilt/data_processing.py` - Caricamento e definizione dati
- [ ] `tilt/conversion.py` - Conversione dati grezzi
- [ ] `tilt/averaging.py` - Media dati
- [ ] `tilt/elaboration.py` - Elaborazione principale
- [ ] `tilt/fukuzono.py` - Analisi Fukuzono
- [ ] `tilt/sensors/biaxial.py` - Calcoli biassiali
- [ ] `tilt/db_write.py` - Scrittura database

#### Modulo ATD
- [ ] `atd/data_processing.py` - Caricamento dati
- [ ] `atd/conversion.py` - Conversione sensori
- [ ] `atd/averaging.py` - Media dati
- [ ] `atd/elaboration.py` - Elaborazione
- [ ] `atd/sensors/` - Implementazione sensori specifici
- [ ] `atd/reports/generator.py` - Generazione report

#### Modulo Monitoring
- [ ] `monitoring/thresholds.py` - Gestione soglie
- [ ] `monitoring/battery_check.py` - Controllo batterie
- [ ] `monitoring/notifications.py` - Notifiche SMS/email

## Pattern di Conversione

### 1. Funzioni MATLAB → Python

#### Input/Output
```matlab
% MATLAB
function [output1, output2] = myFunction(input1, input2)
```

```python
# Python
def my_function(input1: type1, input2: type2) -> Tuple[type3, type4]:
    """Docstring describing function."""
    return output1, output2
```

#### Indicizzazione Array
```matlab
% MATLAB (1-based)
data(1)        % Primo elemento
data(2:5)      % Elementi 2-5
data(end)      % Ultimo elemento
```

```python
# Python (0-based)
data[0]        # Primo elemento
data[1:5]      # Elementi 2-5 (esclude 5)
data[-1]       # Ultimo elemento
```

#### Matrici e Array
```matlab
% MATLAB
A = zeros(10, 5);
A(i,j) = value;
B = A';  % Trasposta
```

```python
# Python (NumPy)
A = np.zeros((10, 5))
A[i,j] = value
B = A.T  # Trasposta
```

### 2. Query Database

#### MATLAB
```matlab
query = 'SELECT * FROM table WHERE id = ?';
data = fetch(conn, query, id);
```

#### Python
```python
query = "SELECT * FROM table WHERE id = %s"
data = conn.execute_query(query, (id,))
```

### 3. File I/O

#### MATLAB
```matlab
data = csvread('file.csv');
xlsread('file.xlsx', 'Sheet1');
```

#### Python
```python
data = np.loadtxt('file.csv', delimiter=',')
df = pd.read_excel('file.xlsx', sheet_name='Sheet1')
```

### 4. Logging

#### MATLAB
```matlab
fileID = fopen(FileName,'a');
fprintf(fileID, '%s\n', text);
fclose(fileID);
```

#### Python
```python
logger.info(text)
# Oppure
with LogFileWriter(filename) as f:
    f.write(text)
```

## Conversione File Specifici

### RSN: defDatiRSN.m → data_processing.py

**Obiettivo**: Organizzare dati grezzi dal database in strutture NumPy.

**Passi**:
1. Ricevere lista di dizionari da query database
2. Estrarre timestamp e convertire in array NumPy
3. Organizzare dati sensori per nodo
4. Gestire valori mancanti
5. Applicare despiking iniziale
6. Restituire arrays strutturati

**Esempio**:
```python
def define_rsn_data(raw_data, n_sensors, mems_type):
    # Estrarre timestamps
    timestamps = np.array([row['timestamp'] for row in raw_data])

    # Inizializzare arrays
    n_points = len(timestamps) // n_sensors
    acc = np.zeros((n_points, n_sensors * (2 if mems_type == 2 else 3)))
    temp = np.zeros((n_points, n_sensors))

    # Riempire arrays
    for i, row in enumerate(raw_data):
        point_idx = i // n_sensors
        sensor_idx = i % n_sensors
        # ... popolare arrays

    return timestamps, acc, temp, errors
```

### Tilt: elaborazione_TL.m → elaboration.py

**Obiettivo**: Calcolare spostamenti da dati inclinometrici.

**Passi principali**:
1. Validazione temperature
2. Controllo vettori accelerazione (se MEMS)
3. Applicazione trasformazioni geometriche (usando geometry.py)
4. Calcolo differenziali rispetto a riferimento
5. Gestione errori

**Funzioni chiave da implementare**:
- `elaborate_tilt_link_data()` - Per TL standard
- `elaborate_tilt_link_hr_data()` - Per TLHR alta risoluzione
- `calculate_biaxial_displacements()` - Per sensori biassiali

### ATD: CalcoloBiax_TuL.m → elaboration.py

**Obiettivo**: Calcoli biassiali per Tube Link.

**Elementi specifici**:
- Correlazione fra assi
- Compensazione temperatura
- Calcolo stella per posizionamento spaziale

### Monitoring: checkBattery.m → battery_check.py

**Semplice**: Query database per livello batteria, confronto soglie, invio notifiche.

```python
def check_battery(battery_level, control_unit_id, unit_type, email_list, conn):
    status = validate_battery_level(battery_level)

    if status == 'critical':
        send_notification(
            email_list,
            subject=f"CRITICAL: Battery {control_unit_id}",
            message=f"Battery level: {battery_level}%"
        )
```

## Testing

### Test Unitari
Creare test per ogni modulo convertito:

```python
# test_conversion.py
import numpy as np
from src.rsn.conversion import convert_rsn_data

def test_convert_rsn_data_freescale():
    # Setup
    n_sensors = 2
    acc = np.array([[100, 200, 150, 250]])  # Raw ADC
    temp = np.array([[2500, 2600]])
    cal = np.array([
        [0.001, 0, 0.001, 0, 0.1, -50],
        [0.001, 0, 0.001, 0, 0.1, -50]
    ])
    mems_type = 2

    # Execute
    acc_conv, acc_mag, temp_conv = convert_rsn_data(
        n_sensors, acc, temp, cal, mems_type
    )

    # Assert
    assert acc_conv.shape == (1, 4)
    assert acc_mag.shape == (1, 2)
    # ... altri assert
```

### Test di Integrazione
Testare flusso completo con dati reali:

```python
def test_rsn_full_pipeline():
    # Usare piccolo subset di dati reali
    # Verificare output atteso
    pass
```

## Checklist per Ogni File Convertito

- [ ] Docstring completo per funzione/classe
- [ ] Type hints per parametri e return
- [ ] Gestione eccezioni appropriata
- [ ] Logging di operazioni importanti
- [ ] Validazione input
- [ ] Test unitari
- [ ] Documentazione in README

## Priorità di Conversione

### Alta Priorità
1. `rsn/data_processing.py` - Necessario per funzionamento base RSN
2. `tilt/elaboration.py` - Core processing tilt sensors
3. `atd/elaboration.py` - Core processing ATD sensors
4. `monitoring/notifications.py` - Sistema allerte critico

### Media Priorità
5. Moduli sensors specifici
6. Report generation
7. Advanced analytics (Fukuzono, etc.)

### Bassa Priorità
8. Report templates
9. Dashboard integration
10. ML features

## Strumenti Utili

### MATLAB to Python Converter (parziale)
```bash
# Librerie che possono aiutare
pip install matlab2python  # Conversione automatica base
pip install smop           # Source-to-source compiler
```

⚠️ **Nota**: La conversione automatica produce codice di bassa qualità. Usare solo come riferimento.

### Confronto Output
Per verificare correttezza conversione:

1. Eseguire versione MATLAB e salvare output
2. Eseguire versione Python con stessi input
3. Confrontare risultati numerici

```python
def compare_outputs(matlab_output, python_output, tolerance=1e-6):
    diff = np.abs(matlab_output - python_output)
    max_diff = np.max(diff)
    print(f"Max difference: {max_diff}")
    assert max_diff < tolerance, "Outputs differ significantly"
```

## Problemi Comuni e Soluzioni

### 1. Differenze Numeriche
**Problema**: Risultati Python leggermente diversi da MATLAB.

**Cause comuni**:
- Differenze floating point precision
- Ordine operazioni diverse
- Funzioni con implementazioni diverse (es. `round`)

**Soluzione**: Accettare differenze < 1e-6, documentare se maggiori.

### 2. Performance
**Problema**: Codice Python più lento di MATLAB.

**Soluzioni**:
- Usare operazioni vettoriali NumPy invece di loop
- Compilare con Numba (@jit decorator)
- Profilare con cProfile per trovare bottleneck

### 3. Memory Usage
**Problema**: Uso eccessivo memoria.

**Soluzioni**:
- Processare dati in chunks
- Usare dtype appropriati (float32 invece di float64 se possibile)
- Liberare memoria con `del` per arrays grandi

## Risorse

- NumPy Documentation: https://numpy.org/doc/
- Pandas Documentation: https://pandas.pydata.org/docs/
- MySQL Connector Python: https://dev.mysql.com/doc/connector-python/
- Python Type Hints: https://docs.python.org/3/library/typing.html

## Contatti

Per domande sulla conversione, consultare:
- Documentazione codice MATLAB originale
- File di log per capire flusso elaborazione
- Database schema per struttura dati
