### **Documento di Analisi: Logica di Parsing del Tool IDL (`Grifo_E_data_reader.pro`)**

**Scopo:**
Questo documento descrive il processo con cui lo script IDL analizza i file di dati `.out`, con un focus sulla struttura dei dati, l'ordine dei blocchi e la logica di raggruppamento. L'obiettivo è definire un comportamento di riferimento per validare la nostra implementazione in Python.

---

#### **1. Principio di Funzionamento Generale**

Lo script opera seguendo un approccio sequenziale ben definito:
1.  **Lettura Globale:** L'intero file `.out` viene caricato in memoria come un unico grande array di parole a 32-bit non segnate (`unsigned long`).
2.  **Scansione dei Marker:** L'array viene scansionato per identificare tutti i possibili punti di inizio dei blocchi di dati, cercando specifici "marker" a 32-bit.
3.  **Classificazione dei Blocchi:** Per ogni marker trovato, lo script analizza l'header che lo segue per determinarne il tipo (es. `DSPHDRIN`, `SUM`, `CDPSTS`, `EXP`) e la dimensione del payload.
4.  **Raggruppamento Logico (Batching):** I blocchi vengono raggruppati in "batch" logici. Un batch rappresenta un ciclo completo di acquisizione ed elaborazione del radar e serve come base per creare una "riga" di dati aggregati.
5.  **Estrazione Dati:** Una volta identificato e raggruppato un blocco, i dati di interesse (in particolare i dati di segnale IQ) vengono estratti dal suo payload.

---

#### **2. Fase di Lettura e Scansione: Come Vengono Trovati i Blocchi**

Questa è la fase fondamentale da cui dipende tutto il resto.

*   **Due Tipi di Marker:** Lo script cerca due marker principali per identificare due famiglie di blocchi:
    *   **`0x5A5A5A5A` (Legacy Blocks):** Sono i blocchi di dati principali generati dal DSP, come `DSPHDRIN`, `SUM`, `GUARD`, `CDPSTS`, etc.
    *   **`0x7A7A7A7A` (Firmware Blocks):** Sono blocchi di stato/configurazione di basso livello, come `EXP` (Expander), `PC` (Pulse Compression) e `DET` (Detector).

*   **Identificazione dell'Inizio Blocco:** Lo script non si fida di un singolo marker. Cerca una sequenza di **due marker identici e consecutivi**. Ad esempio, `0x5A5A5A5A` seguito immediatamente da `0x5A5A5A5A`. L'inizio effettivo del blocco di dati viene considerato a partire dalla prima delle due parole. Questa è una tecnica robusta per evitare falsi positivi.

---

#### **3. Struttura e Classificazione dei Blocchi**

Una volta trovato l'inizio di un blocco, lo script ne determina la natura e la dimensione leggendo a specifici offset (distanze in parole da 32-bit) dall'inizio.

##### **A. Blocchi Legacy (`0x5A5A5A5A`)**

Questa è la famiglia più complessa, poiché usa una logica di identificazione a più livelli.

*   **Dimensione del Payload:** Si trova sempre all'offset `+5` parole. Contiene la dimensione del payload in **bytes**.
*   **ID Primario del Blocco:** Si trova all'offset `+17` parole. È un valore numerico che identifica il tipo di blocco (es. `1213223748` per `DSPHDRIN`).
*   **ID Secondario (Discriminatore):** **Questo è un punto cruciale.** Per alcuni blocchi, l'ID primario non è sufficiente. Lo script legge anche la parola all'offset `+18` per distinguere tra sotto-tipi. Lo schema è:
    *   **Se l'ID a `+17` è `1213223748` (`DSPHDRIN`):**
        *   Se l'ID a `+18` è `1431261764` (`DSPHDROUT`), allora il blocco è un **Header di Output**.
        *   Altrimenti, è un **Header di Input (`DSPHDRIN`)**.
    *   **Se l'ID a `+17` è `1599362131` (`STT_LAA_NAME`):**
        *   Se l'ID a `+18` è `4276556`, allora il blocco è un **blocco di Single Target Track (`STT_LAA`)**.
    *   **Se l'ID a `+17` è `1599362125` (`MTT_LAA_NAME`):**
        *   Se l'ID a `+18` è `4276556`, allora il blocco è un **blocco di Multi Target Track (`MTT_LAA`)**.

##### **B. Blocchi Firmware (`0x7A7A7A7A`)**

Questi sono più semplici.
*   **ID del Blocco:** Si trova all'offset `+2` parole.
*   **Dimensione del Payload:** Si trova all'offset `+5` parole (in bytes).
*   **Inizio del Payload:** I dati utili iniziano dopo l'header del blocco, che è lungo 8 parole.

---

#### **4. Logica di Raggruppamento: Cosa Costituisce un "Batch"**

Questa è la logica che dobbiamo replicare per evitare i duplicati.
*   **L'Inizio di un Batch:** Un nuovo batch logico **inizia esclusivamente con un blocco `DSPHDRIN`**.
*   **Contenuto di un Batch:** Un batch è costituito dal blocco `DSPHDRIN` che lo avvia e da **tutti i blocchi di dati successivi** (`CDPSTS`, `D1553`, segnali `SUM`/`GUARD`, blocchi di output come `DSPHDROUT` e `STT_LAA`) fino a quando non si incontra il successivo blocco `DSPHDRIN`.
*   **Blocco `DSPS`:** Sebbene sia un blocco di stato, lo script IDL lo tratta in modo simile a un `DSPHDRIN` di input, usandolo per estrarre informazioni di stato ma non per avviare un nuovo raggruppamento. **La nostra logica Python finale che raggruppa tutto sotto il `DSPHDRIN` precedente è la rappresentazione corretta di questo comportamento.**

**Schema di un Batch Tipico:**
Un batch logico nel file `.out` ha tipicamente questa sequenza:
1.  **Blocco `DSPHDRIN`** (Contiene il `batch_counter`, `N_PRI`, `N_RBIN` per questo ciclo)
2.  Blocco `CDPSTS` (Stato del processore)
3.  Blocco `D1553` (Dati avionici)
4.  Blocco `SUM` (Segnale IQ del canale Somma)
5.  Blocco `GUARD` (Segnale IQ del canale Guardia)
6.  ... (altri segnali) ...
7.  **Blocco `DSPHDROUT`** (Risultati dell'elaborazione per lo stesso `batch_counter`)
8.  **Blocco `STT_LAA`** (Dati di tracking per lo stesso `batch_counter`)
9.  ... (altri blocchi di output) ...
*(Il prossimo blocco `DSPHDRIN` nel file segnerà l'inizio del batch successivo)*

---

#### **5. Estrazione dei Dati di Segnale (IQ)**

Per i blocchi che contengono dati di segnale grezzo (es. `SUM`, `GUARD`, `DAZ`, `DEL`):
1.  Lo script non legge i dati dall'inizio del payload.
2.  Cerca un **marker secondario** all'interno del payload: `0x4E474953` (che in ASCII corrisponde a "NGIS").
3.  I dati IQ effettivi iniziano **2 parole dopo** questo marker "NGIS".
4.  Le dimensioni per ricostruire la matrice del segnale (`N_PRI` e `N_RBIN`) vengono prese dall'header `DSPHDRIN` del batch corrente. Questa è una dipendenza di stato fondamentale.

---

### **Punti Chiave per la Verifica della Nostra Applicazione**

Per essere certi che la nostra applicazione Python si comporti come il tool IDL, dobbiamo verificare i seguenti punti:

1.  **[✓] Raggruppamento per `DSPHDRIN`:** La logica di `file_reader.py` deve raggruppare tutti i blocchi successivi sotto l'ultimo `DSPHDRIN` incontrato.
2.  **[✓] Identificazione a Doppio Livello:** Lo `struct_parser.py` deve implementare la logica del "discriminatore" (parola a offset +18) per distinguere correttamente `DSPHDROUT`, `STT_LAA`, etc.
3.  **[✓] Offset di Payload Corretti:** Dobbiamo assicurarci che per ogni tipo di blocco (`DSPHDROUT`, `STT_LAA`, etc.) si usi l'offset corretto per iniziare a leggere il payload (es. 144 byte per `DSPHDROUT`, 152 per `STT_LAA`).
4.  **[ ] Gestione Completa dei Blocchi:** Dobbiamo mappare e parsare tutti i tipi di blocco menzionati nell'IDL che sono rilevanti per l'output, come `MTT_LAA`, `SLBCRES`, etc. (questo sarà il nostro lavoro futuro).
5.  **[✓] Dipendenza da Header per i Segnali:** Il parsing dei blocchi di segnale (`SUM`, etc.) deve utilizzare i parametri `N_PRI` e `N_RBIN` presi dall'header del batch a cui appartengono.