Fri Mar 14 12:49:51 CET 2008

########################## HOW TO COMPILE ####################################

Il nome dell'eseguibile e' chewbacca 

Scompattare la cartella.
Andare nella cartella /PamelaSW e settare variabili d'ambiente utili.
[PamelaSW]$ . set_env.sh
In particolare servono le variabili utili per utilizzare le funzionalita' di ROOT ($ROOTSYS)

Creare DB: yoda_db 
user:  yoda_user 
pwd:   yoda_pwd 	
Per creare le tabelle usare "/PamelaSW/DBScript/db.sql"

Da PamelaSW e' possibile fare make per buildare tutto.
Tutti i Makefile sono stati riscritti.
Non serve piu' digitare "aclocal autoheader libtool automake autoconf configure" ne settare tutte le variabili d'ambiente necessarie a Yoda e Log4cxx. 
Si utilizzano soltanto i Makefile nelle varie directory ed eventualmente si devono modificare i Make.def relativi.

Nella cartella /PamelaSW/event/ c'e' la libreria Yoda (libyoda.so)
Si linka dinamicamente e quindi serve export LD_LIBRARY_PATH=$BASEDIR/event:$LD_LIBRARY_PATH
La libreria libyoda.so si puo buildare separatamente dalla cartella "/PamelaSW/event/".
Per informazioni aggiuntive su come buildare digitare: [PamelaSW/event]$ make help
Questa parte contiene le classi  "Packet Event" come nella versione originale (yoda).
Le modifiche sono state volte principalmente alla sostituzione del sistema di logging e alla soluzione di alcuni bugs. 
Inoltre la classe RunInfo e' stata sostituita da RunInfoYoda.

Il sorgente dell'eseguibile "chewbacca" e' in /PamelaSW/PamOffLineSW.
Per informazioni aggiuntive su come buildare digitare: [PamelaSW/PamOffLineSW]$ make help
In questa parte si trovano tutte le classi nuove necessarie a parserare il file di input alla ricerca e identificazione di un pacchetto pamela.
Per ogni pacchetto trovato e' possibile determinare se puo' essere considerato consecutivo al precedente o meno e quindi creare un file di ROOT per ogni gruppo di pacchetti continui trovati.

Nella sottocartella /PamelaSW/PamOffLineSW/forroutines/ viene creata la libreria libforrou.a linkata staticamente da chewbacca.
Questa sostanzialmente non e' stata modificata rispetto la versione originale.
Per informazioni aggiuntive su come buildare digitare: [PamelaSW/PamOffLineSW/forroutines]$ make help

Nella sottocartella /PamelaSW/PamOffLineSW/physics/ viene creata la libreria libdevreaders.a linkata staticamente da chewbacca.
Le modifiche qui sono state principalmente relative alla sostituzione del sistema di logging.
Per informazioni aggiuntive su come buildare digitare: [PamelaSW/PamOffLineSW/physics]$ make help

Nella sottocartella /PamelaSW/PamOffLineSW/techmodel/ viene creata la libreria libtechmodel.a linkata staticamente da chewbacca.
Questa parte contiene le classi "Packet Reader".
Evidentemente qui le modifiche sono state parecchie rispetto la versione originale di Yoda.
Nella vecchia versione c'era bisogno di un file di input (l'output del RawReader) che veniva parserato e di volta in volta chiamava il "reader" appropriato per il giusto tipo di pacchetto trovato.
Nella nuova versione il pacchetto e' gia stato correttemente evidenziato dal modulo precedente ed arriva come un buffer al modulo reader.
Questo implica che il modulo viene chiamato una volta per ogni pacchetto trovato, quindi e' stato necessario correggere tutte le parti di codice che portavano a memory leaks.
Sono stati risolti anche molti altri bugs e imprecisioni nelle varie classi.  
Per informazioni aggiuntive su come buildare digitare: [PamelaSW/PamOffLineSW/techmodel]$ make help

###################### USAGE ####################################

[PamelaSW/PamOffLineSW]$ ./chewbacca INPUT_FILE [OPTIONS]

Le possibili opzioni e il modo di utilizzare l'eseguibile vengono mostrate digitando il seguente comando:
[PamelaSW/PamOffLineSW]$ ./chewbacca -help

Esempio di utilizzo tipico:
[PamOffLineSW]$ ./chewbacca /PamelaSW/data/input/08152004.pam -outDir /PamelaSW/data/08152004/ -filelog /PamelaSW/data/08152004/logfile.txt -loglevel 3 -vrl -delta_counter 5 

Per cambiare i parametri relativi al DB si possono usare le seguenti opzioni:  
         -db_host   set the host-name of the DataBase.  [default = localhost]
         -db_port   set the port of the DataBase.  [default = 3306]
         -db_name   set the name of the DataBase.  [default = yoda_db]
         -db_user   set the user of the DataBase.  [default = yoda_user]
         -db_pwd    set the user of the DataBase.  [default = yoda_pwd]

Se il file di input contiene dati simulati senza header VRL si deve usare l'opzione -simu.
Tale opzione e' utile anche se vuole utilizzare come input un file ottenuto come output del vecchio RawReader.

Per variare la verbosita' dei messaggi salvati nel file di log e' possibile utilizzare l'opzione:
         -loglevel     set the log level. Values: [0,3](error,warning,info,all) [default:0]
Il valore suggerito e' loglevel = 2 (info)
Il nome del file di log e configurabile usando l'opzione:
         -filelog     set the log filename. [default: pamofflinesw.log]

Per abilitare i check sulla continuita' dei pacchetti e' necessario utilizzare le opzioni:
   	-delta_counter  set the allowed difference in the Packet Counter between two continuos packets. If 0 all packets are considered continuos.  [default = 0]
        -delta_obt      set the allowed difference (ms) in the Packet Orbital Time between two continuos packets. If 0 all packets are considered continuos.  [default = 0]

I valori suggeriti sono delta_counter=5  delta_obt=0 (unused)

Il DB viene utilizzato, come spiegato meglio in seguito, solo se  vengono fatti controlli relativi alla discontinuita' e quindi solo se delta_counter (e/o delta_obt) e' diverso da zero.
I ROOT file finali conterranno in tal caso ognuno un set continuo di pacchetti.

In caso contrario (delta_counter=delta_obt=0) chewbacca si comportera' come se avessi usato in serie il vecchio RawReader e Yoda, ossia creera' N file di ROOT uno per ogni download trovato nel file di input.

Il nome del file di input deve essere del tipo nnnnnmmm.pam
Da questo vengono infatti estratti l'orbit number = nnnnn e il session number = mmm
In caso si usasse un file con nome diverso si possono usare le seguenti opzioni per settare tali valori:
	 -orbit_number    Value of the orbital number. If 0 this is retrieved from the input file name.  [default = 0]
         -session_number  Value of the session number. If 0 this is retrieved from the input file name.  [default = 0]

Evidentemente il file di input deve esistere.
L'informazione con il path completo  del file di input viene salvato nel file di log e nel DB finale.

Mentre leggo l'input ogni volta che identifico un nuovo download incremento una variabile che rappresenta il download_number.
Per ogni download all'interno di uno stesso downlink sicuramente ho un discontinuita', e quindi almeno un file di ROOT per ogni download.

I ROOT file finali avranno nome del tipo: (root_name)_(orbit_number)_(session_number)_(download_number)_(N).root
dove root_name = parte iniziale del nome e' configurabile da riga di comando usando l'opzione:
 	-root_name      set the root-name for the generated ROOT file(s). [default = yoda]
e N e' un contatore per il numero di discontinuita' trovate.

Durante la lettura del file di input ogni cadre viene controllata se e' abilitata l'opzione -vrl.
Se la cadre e' "non buona" (ad esempio se il check del CRC fallisce) tutti i pacchetti che hanno una parte dei dati contenuti nella suddetta cadre vengono etichettati come pacchetti non buoni (BAD_PKT).

Per ogni download viene ricavato il time_Offset necessario per calcolare il tempo assoluto.      
Nel caso si conosca il time_Offset ed questi sia lo stesso per tutto il downlink si puo' usare l'opzione:
	-time_Offset  Value of the timeOffset. If 0 this is retrieved using the orbital number.  [default = 0]

Il timeOffset viene ottenuto attraverso una query al DB.
In particolare si legge dalla tabella yoda_db.GL_RESURS_OFFSET in modo analogo a quanto attualmente fa' YodaProfiler.

Un pacchetto viene trovato se tra i dati di una o piu' cadres consecutive ci sono 16 bytes consecutivi che iniziano per "0xFA 0xFE 0xDE" e che passano il check sul CRC.

Analizzando l'header del pacchetto vengono estratte le informazioni sul Packet Counter e OBT.
Comparando questi valori con i valori del pacchetto precedentemente utilizzato e' possibile stabilire se il pacchetto e' da considerarsi consecutivo rispetto al precedente o meno.

Il ROOT file finale contiene un set continuo di pacchetti se il check sulla continuita' e' abilitato.
Ogni volta infatti che una discontinuita' viene trovata viene chiuso e salvato un file di ROOT contenente i pacchetti precedentemente arrivati e viene aperto un nuovo file di ROOT che conterra' il successivo set di pacchetti continui.

Un pacchetto e' considerato consecutivo al precedente se la differenza tra il packet counter del pacchetto corrente e quello del pacchetto precedente DELTA_PC soddisfa la seguente condizione:
DELTA_PC < delta_counter (valore configurabile da linea di comando usando -delta_counter)
Nel caso il pacchetto passi il check di continuita' sul Packet Counter viene fatto un chek analgo utilizzando il Packet OBT 

Per ogni download se trovo un packetto di tipo RunHeader o RunTrailer ricavo i valori necessari al time sync ossia: OBT_TIME_SYNC e LAST_TIME_SYNC_INFO.
Utilizzando i valori dell' OBT iniziale e finale e il TIME_OFFSET puo' essere ricavato il tempo assoluto del primo e dell'ultimo pacchetto:
real_time_init= (obt_init/1000-obt_time_sync)+last_time_sync_info + timeOffset; 
real_time_last= (obt_last/1000-obt_time_sync)+last_time_sync_info + timeOffset;	

In questo modo un set continuo di pacchetti puo' essere associato ad un determinato intervallo temporale.

Ogni pacchetto viene passato al modulo "Packet Reader" nel quale a seconda del tipo di pacchetto viene analizzato utilizzando le appropriate classi.
In questo modulo sono definite piu tipi di eccezioni.
Nei casi in cui il pacchetto e' per qualche motivo da considerarsi "non buono', questi non viene utilizzato e aggiunto al ROOT file.
In alcuni casi invece il pacchetto viene utilizzato come se fosse un pacchetto buono a tutti gli effetti pur non avendo passato alcuni check, ad esempio check sul CRC dei sottopacchetti.
In questi casi viene loggato un warning nel file di log e il pacchetto e' etichettato come un pacchetto non buono (BAD_PKT_READ) ma comunque salvato nel file di ROOT.
I pacchetti di calibrazione che per qualche motivo vengono considerati non buoni seppur salvati nel ROOT file vengono etichettati come non buoni ma utilizzando una etichetta diversa BAD_PKT_CALREAD e loggando un messaggio di errore nel file di log.
Le informazioni relative ai file di calibrazione con errore vengono inoltre salvate sul DB nella tabella BAD_PKT_TABLE.
In questa tabella si salva il suo Packet_counter, l'OBT e il nome del ROOT file che lo contiene.

Nella versione attuale tutti i pacchetti di calibrazione trovati vengono considerati non buoni.
Inoltre questi pacchetti vengono anche salvati su file in modo da poter essere controllati separatamente in seguito.
Il nome di questi file e'del tipo pkt12728_of_yoda_07790_001_002_0.pkt ossia numero del paccketto 12728 salvato nel ROOT file di nome "yoda_07790_001_002_0".
Questa funzionalita' verra' presto rimossa o abilitata facoltivamente utilizzando un apposita opzione.

Quando un file di ROOT viene chiuso e salvato se il check sulla continuita' dei pacchetti e' stato abilitato vengono salvate sul DB tutte le informazioni relative al file di ROOT.

In particolare se non e' stato possibile associare un tempo assoluto al gruppo di pacchetti in questione, e cio' accade se tra di essi non c'e' nessun pacchetto buono di tipo RunHeader o RunTrailer, il record viene salvato nella tabella ROOT_TABLE_BAD altrimenti nella tabella ROOT_TABLE.
In queste tabelle si salva il numero di pacchetti salvati, 
il numero di pacchetti di calibrazione con errore BAD_PKT_CALREAD,
il numero di pacchetti con errore BAD_PKT_READ e quelli senza errore ma comunque provenienti da una o piu cadre che non hanno superato i check vrl BAD_PKT oltre alle informazioni relative al primo e l'ultimo pacchetto del gruppo.
Con queste informazioni e' possibile tentare di fare a posteriori una operazione di merge/clean tra piu file di ROOT che coprono intervalli temporali parzialmente sovrapponibili scegliendo ad esempio quelli che hanno un minor numero di pacchetti con errore.
Si e' scelto di separare il numero di pacchetti di calibrazione con errore dagli altri tipi di errore in quanto per una analisi corretta e' necessario che questi pacchetti siano affidabili.

Se si vuole tentare la prima versione del Merging si puo' usare l'opzione:
         -tryMerge if you want to try to Merge ROOT files

In questo caso viene riempita la tabella ROOT_TABLE_ASS nel DB.
Cosi facendo per ogni file di ROOT che contenga almeno 2 pacchetti buoni si cercano tutti i file di ROOT (con almeno 2 pacchetti buoni) gia' presenti nel DB che coprano un intervallo temporale di interesse.
Nella tabella ROOT_TABLE_ASS per ogni record si salva l'ID relativo al ROOT file in questione e quello del ROOT file ad esso associato dalla tabella ROOT_TABLE e il tipo di associazione trovato.
In particolare i tipi di associazione sono espressi da interi:
0 =AFTER   se temporalmente viene subito dopo il ROOT file associato		
1 =AFTER2  se c'e' una sovrapposizione temporale parziale, inizia dopo l'inizio di quello associato e finisce dopo la sua fine
2 =BEFORE  se temporalmente viene subito prima del ROOT file associato	
3 =BEFORE2 se c'e' una sovrapposizione temporale parziale, ossia finisce prima della fine di quello associato ma inizia prima
4 =SMALLER se c'e' una sovrapposizione temporale parziale: e' contenuto nel ROOT file associato
5 =BIGGER  se c'e' una sovrapposizione temporale parziale: contiene il ROOT file associato

Per ogni record nel DB viene inoltre salvato un ID incrementale unico e il tempo in cui questo record e' stato insertito.

