Index: /trunk/AddOn/TAcq/brpaqu.cc
===================================================================
--- /trunk/AddOn/TAcq/brpaqu.cc	(revision 3591)
+++ /trunk/AddOn/TAcq/brpaqu.cc	(revision 3592)
@@ -11,26 +11,154 @@
 }
 
-BRPaquet::BRPaquet(Byte* src, Byte* dst, int paqsz)
+/* --Methode__ */
+BRPaquet::BRPaquet(Byte* src, Byte* dst, int paqsz, BRDataFmtConv fgswap)
+  // swapall = true -> on swap tout le paquet, sinon swap entete seulement
 {
   dst_ = dst;
   sz_ = paqsz;
-  if ((src==NULL)||(dst==NULL))  return;
-  // On copie l'entete sans swapper 
-  for(int k=0; k<BRHDRSIZE; k++)  dst_[k] = src[k];
-  // On copie la zone donnees en faisant un byte-swap correspondant a 4 octets 
-   for(int ka=BRHDRSIZE; ka<sz_-BRTRLSIZE; ka+=4) {
-    for(int kb=0; kb<4; kb++)
-      dst_[ka+kb] = src[ka+3-kb];
+  if ((src == NULL) || (dst == NULL)) return;
+  // Il faut mettre une protection (throw) si dst==NULL ou sz==0
+
+  UInt32* src32 = (UInt32*)src;
+  UInt32* dst32 = (UInt32*)dst;
+
+  switch ( fgswap ) {
+  case BR_DoNothing :  // rien a faire
+    break;
+  case BR_Copy : // copie directe 
+    memcpy(dst_, src, sz_); 
+    break;
+  case BR_Swap32 : // On swappe toutes les donnees du paquet 
+  //  les bytes sont dans l'ordre par paquet de 4 octets (Int32) , les deux Int32 de 
+  // On copie la zone donnees en faisant un byte-swap correspondant a 8 octets (4->8 Reza/firmware SGDMA) 
+    for(int ka=0; ka<sz_/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+   
+    break;
+  case BR_SwapAll:
+  for(int ka=0; ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+        dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    for(int ka=HeaderSize()+DataSize(); ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    break;
+  case BR_SwapHDR :
+  case BR_FFTOneChan :
+  case BR_FFTTwoChan :
+    // ByteSwap 8 (4->8 Reza/firmware SGDMA) de l'enete 
+    for(int ka=0; ka<BRHDRSIZE; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+
+    if (fgswap == BR_FFTOneChan) ReorderFFTData(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChan) {
+      ReorderFFTData(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTData(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    for(int ka=HeaderSize()+DataSize(); ka<sz_; ka+=8) {
+      for(int kb=0; kb<4; kb++) {
+	dst_[ka+kb] = src[ka+3-kb+4];    
+        dst_[ka+kb+4] = src[ka+3-kb];    
+      }
+    }
+    break;
+ 
+  case BR_FFTOneChan32 :
+  case BR_FFTTwoChan32 :
+    // on swappe tout  en attendant le swap general sinon il faut encore crÃ©er une fonctiondifferente de ReorderFFT
+    // swapp du header uniquement
+    for(int ka=0; ka<BRHDRSIZE/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+  
+    // on reoordonne et on swappe en mem temps
+    if (fgswap == BR_FFTOneChan32) ReorderFFTData32(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChan32) {
+      ReorderFFTData32(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTData32(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    // swap du trailler uniquement
+    for(int ka=(HeaderSize()+DataSize())/4;ka < sz_/4; ka+=2) {
+      dst32[ka] = src32[ka+1];
+      dst32[ka+1] = src32[ka];
+    }
+    
+  case BR_FFTOneChanNoSwap :
+  case BR_FFTTwoChanNoSwap :
+    // on a plus de swapdonc il faut copier dans dst
+    memcpy(dst_, src, sz_); 
+    // on reoordonne et on swappe en mem temps
+    if (fgswap == BR_FFTOneChanNoSwap) ReorderFFTDataNoSwap(src+HeaderSize(), dst_+HeaderSize(), DataSize());
+    else if (fgswap == BR_FFTTwoChanNoSwap) {
+      ReorderFFTDataNoSwap(src+HeaderSize(), dst_+HeaderSize(), DataSize()/2);
+      ReorderFFTDataNoSwap(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
+    }
+    
+    break;
+  }  // Fin switch 
+
+}
+
+/* --Methode__ */
+BRPaquet::BRPaquet(Byte* srcdst, int paqsz)
+{
+  dst_ = srcdst;
+  sz_ = paqsz;
+  // Il faut mettre une protection (throw) si srcdst==NULL ou sz==0
+}
+
+
+/* --Methode__ */
+UInt16 BRPaquet::ChannelID()
+{
+
+  UInt16 ChnId=ChanId();
+  UInt16 ChpId=ChipId();
+ 
+     
+  if (ChpId == 2) 
+    {
+      if (ChnId == 1) ChnId = Ch3;
+      if (ChnId == 2) ChnId = Ch4;
+      if (ChnId == 3) ChnId = Ch3_4;
+    }
+  return(ChnId);
+}
+
+/* --Methode__ */
+UInt16 BRPaquet::ModeAcquisition()
+{
+  UInt16 ModAq;
+  printf("Mod Acq %x \n",ModeAcq());
+  ModAq = ((ModeAcq() & 0x30)>> 4);
+  return(ModAq);
+  
+}
+
+/* --Methode__ */
+void BRPaquet::Print(ostream & os, int nelt, bool prht)
+{
+  os << endl << "BRPaquet::Print() PaqSz=" << PaquetSize() << " DataSize=" << DataSize() 
+     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl;
+  if (dst_ == NULL) {
+    os << " ...NULL paquet " << endl;
+    return; 
   }
-  // On copie le trailer sans swapper 
-  for(int k=sz_-1; k>=sz_-BRTRLSIZE; k--)  dst_[k] = src[k];
-
-}
-
-
-void BRPaquet::Print(ostream & os, int nelt, bool prht)
-{
-  os << "BRPaquet::Print() PaqSz=" << PaquetSize() << " DataSize=" << DataSize() 
-     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl;
+
+  os << endl << " BR AcqMode: " << ModeAcquisition() << " Channel: " << ChannelID()  << endl;
+
   if (TrailerSize() > 0) 
     os << " ...HDRMarker(hex)=" << hex <<  HDRMarker() << " TRLMarker=" << TRLMarker() << dec << endl;
@@ -38,14 +166,15 @@
     os << " ...HDRMarker(hex)=" << hex <<  HDRMarker() << " NO TRLMarker=" << dec << endl;
   UInt32 tt1, tt2; 
-//  tt2 = (TimeTag()&0xFFFFFFFF00000000) >> 32; 
-  tt2=0; 
-  tt1 = TimeTag()&0x00000000FFFFFFFF;
-  os << " ...TimeTag (hex)=" << hex << TimeTag() << " TT1= " << tt1 << " TT2=" << tt2 << dec << endl;
+  tt2 = TimeTag1(); 
+  tt1 = TimeTag2();
+  os << " ...TimeTag (hex)=" << hex << "TimeTag()" << " TT1= " << tt1 << " TT2=" << tt2 << dec << endl;
+  // os << " ...Position Chariot (hex)= " << hex << PositionChariot() << endl;
   if (nelt > DataSize()/2) nelt = DataSize()/2;
   os << " ...Data[1.." << nelt << "]= ";
-  for(int k=0; k<nelt; k++) os << (int)(*(Data()+k)) << " , ";
+
+  for(int k=0; k<nelt; k++) os << (int)(*(Data1()+k)) << " , ";
   os << endl;
   os << " ...Data[" << DataSize()-nelt << ".." << DataSize()-1 << "]= ";
-  for(int k=DataSize()-nelt; k<DataSize(); k++) os << (int)(*(Data()+k)) << " , ";
+  for(int k=DataSize()-nelt; k<DataSize(); k++) os << (int)(*(Data1()+k)) << " , ";
   os << endl;
   if (prht) {   // Impression header / trailer
@@ -64,2 +193,238 @@
   }
 }
+
+
+// ---------------------------------------------------------
+//  **** REMARQUE   N/2+1 complexes -> N/2 complexes *****
+// N = Nb d'echantillon en temps -> N/2 paires (real, imag)
+// Il y a le continu, et N/2 frequences ---> N/2+1 nombres complexes,
+// mais avec la contrainte Z(0).imag = 0  Z(N/2).imag = 0 
+// f(i) i=0...N-1   ===> Z(k) ( Z complexe , k=0...N/2 )
+// mais avec la contrainte Z(0).imag = 0  Z(N/2).imag = 0 
+// On peut donc tout mettre ds N/2 complexes en choisissant 
+// de mettre ds Z(0).imag  Z(N/2).real 
+// ---------------------------------------------------------- 
+
+// Fonction magique qui donne le pointeur permettant de tenir compte du byte-swp sur 8 octets
+static inline int IndexByteSwap8(int idx) 
+{
+  return ( (idx-(idx%8))+(7-idx%8) ) ;
+}
+
+/* --Methode__ */
+void BRPaquet::ReorderFFTData(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+ 
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[IndexByteSwap8(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[IndexByteSwap8(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[IndexByteSwap8(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[IndexByteSwap8(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[IndexByteSwap8(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[IndexByteSwap8(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[IndexByteSwap8(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[IndexByteSwap8(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+
+static inline int IndexByteSwap8_32(int idx) 
+{
+  return ( (idx-(idx%8))+((4+idx%8)%8) ) ;
+}
+
+void BRPaquet::ReorderFFTData32(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[IndexByteSwap8_32(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[IndexByteSwap8_32(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[IndexByteSwap8_32(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[IndexByteSwap8_32(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[IndexByteSwap8_32(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[IndexByteSwap8_32(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[IndexByteSwap8_32(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[IndexByteSwap8_32(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+void BRPaquet::ReorderFFTDataNoSwap(Byte* src, Byte* dst, int N)
+{
+  // Code recopie depuis /Dev/DisplayData/HistoWindow.cc 
+  // fonction TraceWind::DisplayBaoDatasFFT() et adapte aux structures BRPaquet et Cie 
+  // Modif par rapport au code de Bruno : N/2 elements complexes au lieu de N/2+1 - Remarque ci-dessus
+ 
+  int nCoef = N / 2; // to change
+  int debutIndex = N / 4 + 1;
+  int fifoSize =  N / 4 - 1;
+  int i; 
+
+  TwoByteComplex* dstcmplx = (TwoByteComplex*)dst;
+  
+  //   cout << " Display BAO Datas FFT (" << N << ")" << " : from 0 to "<< nCoef << endl;
+  //   cout << " Variables : debutIndex, fifoSize " << debutIndex << ", " << fifoSize << endl;
+
+  
+  // Sortie 1
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[debutIndex + i].realB() = src[(2*i)];
+      dstcmplx[debutIndex + i].imagB() = src[(2*i + 1)];
+    }
+
+  // element au milieu
+  dstcmplx[N / 4].realB() = src[(2*fifoSize)];
+  dstcmplx[N / 4].imagB() = src[(2*fifoSize + 1)];
+
+  // Sortie 2
+  for (i = 0; i < fifoSize ; i++)
+    {
+      dstcmplx[fifoSize - i].realB() = src[(nCoef + 2*i)];
+      dstcmplx[fifoSize - i].imagB() = src[(nCoef + 2*i + 1)];
+    }
+
+  // k = 0 et k = N/2  
+  dstcmplx[0].realB() = src[(N - 2)];
+  // Voir Remarque ci-dessus Z(N/2).real -> Z(0).image
+  dstcmplx[0].imagB() = src[(N - 1)];  // Attention, on met ici la real(fmax)
+
+  return ; 
+}
+
+/* --Methode__ */
+const char* BRPaquet::FmtConvToString(BRDataFmtConv fgswap)
+{
+  const char * rs="";
+  switch ( fgswap ) {
+  case BR_DoNothing :  
+    rs = "BR_DoNothing";
+    break;
+  case BR_Copy : 
+    rs = "BR_Copy";
+    break;
+  case BR_SwapAll : 
+    rs = "BR_SwapAll";
+    break;
+  case BR_SwapHDR :
+    rs = "BR_SwapHDR";
+    break;
+  case BR_FFTOneChan :
+    rs = "BR_FFTOneChan";
+    break;
+  case BR_FFTTwoChan :
+    rs = "BR_FFTTwoChan";
+    break;
+  case BR_Swap32 :
+    rs = "BR_Swap32";
+    break;
+  case BR_FFTOneChan32 :
+    rs = "BR_FFTOneChan32";
+    break;
+  case BR_FFTTwoChan32 :
+    rs = "BR_FFTTwoChan32";
+    break;
+  case BR_FFTOneChanNoSwap :
+    rs = "BR_FFTOneChanNoSwap";
+    break;
+  case BR_FFTTwoChanNoSwap :
+    rs = "BR_FFTTwoChanNoSwap";
+    break;
+  default:
+    rs = "?????";
+    break;
+  }  // Fin switch 
+  return rs;
+}
+
+// --------------------------------------------------------------------------
+// Classe pour effectuer des verifications d'integrite sur les paquets/frames
+// --------------------------------------------------------------------------
+
+BRPaqChecker::BRPaqChecker()
+{
+  totnframes = 0;
+  nframeok = 0;
+  lostframes = 0;
+  frclst = 0;
+}
+
+BRPaqChecker::~BRPaqChecker()
+{
+}
+
+bool BRPaqChecker::Check(BRPaquet& paq)
+{
+  totnframes++; 
+  if (paq.HDRMarker() != 0x76543210) return false;
+  unsigned int curfc = paq.FrameCounter();
+  unsigned int delfc = 0;
+  if (nframeok > 0) {
+    if (curfc>frclst)  delfc = (curfc-frclst);
+    else delfc = (65535-frclst+curfc);
+    lostframes += (unsigned long long)delfc - 1;
+  }
+  nframeok++; frclst = curfc; 
+  return true;
+}
+
+ostream& BRPaqChecker::Print(ostream& os)
+{
+  os << "BRPaqChecker:  Tot.Nb.Frames.Proc=" << totnframes << " NbFrameOK=" << nframeok 
+     << " LostFrames=" << lostframes 
+     << " Loss=" << (double)lostframes*100./(double)totnframes << " %" << endl;
+  return os;
+}
Index: /trunk/AddOn/TAcq/brpaqu.h
===================================================================
--- /trunk/AddOn/TAcq/brpaqu.h	(revision 3591)
+++ /trunk/AddOn/TAcq/brpaqu.h	(revision 3592)
@@ -12,18 +12,95 @@
 #include "brtypes.h"
 
+
 using namespace std;
 
+// On definit une classe TwoByteComplex() pour manipuler une paire de byte 
+// representant partie relle et imaginaire d'un nombre complexe
+// Remarque Byte = unsigned char 
+// Remarque SByte = char = signed char 
+class TwoByteComplex {
+ public:
+  explicit TwoByteComplex() { val_[0] = val_[1] = 0; }
+  //  explicit TwoByteComplex(TwoByteComplex const & a) { val_[0] = a.val_[0]; val_[1] = 0; }
+  explicit TwoByteComplex(Byte re, Byte im) { val_[0] = re; val_[1] = im; }
+  explicit TwoByteComplex(SByte re, SByte im) { val_[0] = re; val_[1] = im; }
+  explicit TwoByteComplex(int re, int im) { val_[0] = re; val_[1] = im; }
+  explicit TwoByteComplex(float re, float im) { val_[0] = re; val_[1] = im; }
+  explicit TwoByteComplex(double re, double im) { val_[0] = re; val_[1] = im; }
+  
+  inline Byte& realB() { return  val_[0]; }
+  inline Byte& imagB() { return  val_[1]; }
+
+  inline SByte realSB() { return  ((SByte*)val_)[0]; }
+  inline SByte imagSB() { return  ((SByte*)val_)[1]; }
+
+  inline int realI() { return  ((SByte*)val_)[0]; }
+  inline int imagI() { return  ((SByte*)val_)[1]; }
+
+  inline double realD() { return  ((SByte*)val_)[0]; }
+  inline double imagD() { return  ((SByte*)val_)[1]; }
+
+  Byte val_[2];
+};
+
+// Actuellement apres test Nancay un mot de 4octects est mis avant le header
+#define OFFSET 0 
 // Taille entete/trailer en octets 
 #define BRHDRSIZE 24
 // Actuellement le trailer est vire ...
-/* #define BRTRLSIZE 16  */
-#define BRTRLSIZE 0
+// Reza, 28 Jan 2009  le trailer fait 16 octets 
+#define BRTRLSIZE 16  
+/* REZA passe a 16 octets  #define BRTRLSIZE 40 */
+//Offset Mode Acq 
+#define BRMODACQOFF  20 /*RezaMOD #define BRMODACQOFF  24 */
+// Offset ChanId
+#define BRCHANIDOFF 20 /*RezaMOD #define BRCHANIDOFF 24 */
 // Offset du time-tag
-#define BRTMTAGOFF 8
+#define BRTMTAGOFF 12 /*RezaMOD #define BRTMTAGOFF 16 */
+// offset FrameCounter
+#define BRFRCPTOFF 16 /*RezaMOD#define BRFRCPTOFF 20 */
+// offset Paquet Id 
+#define BRPKTIDOFF 20  /*RezaMOD #define BRPKTIDOFF 24 */
+// offset paquet lenght = FrameDataLength 
+#define BRPKTLENOFF 8 /*RezaMOD #define BRPKTLENOFF 12 */
+// offset position chariot ???
+//#define BRPCOFF 16
+
+enum ChannelID
+  {
+    None=0,
+    Ch1,
+    Ch2,
+    Ch1_2,
+    Ch3,
+    Ch4,
+    Ch3_4
+  };
+enum ModeAcq
+  {
+    RawData=1,
+    FFT
+  };
+
+// Definition des actions sur la conversion de format (swap...) des donnees arrivant
+enum BRDataFmtConv {
+  BR_DoNothing,
+  BR_Copy,
+  BR_SwapAll,
+  BR_SwapHDR,
+  BR_FFTOneChan,
+  BR_FFTTwoChan,
+  BR_Swap32,
+  BR_FFTOneChan32,
+  BR_FFTTwoChan32,
+  BR_FFTOneChanNoSwap,
+  BR_FFTTwoChanNoSwap
+};
 
 // Structure correspondant a HEADER-DATA-TRAILER
 class BRPaquet {
  public:
-  BRPaquet(Byte* src, Byte* dst, int paqsz=4096);
+  BRPaquet(Byte* src, Byte* dst, int paqsz=4096, BRDataFmtConv fgswap=BR_SwapAll);
+  BRPaquet(Byte* srcdst, int paqsz=4096);
   //  ~BRPaquet();
 
@@ -31,22 +108,42 @@
   inline int PaquetSize() { return sz_; }
   inline int DataSize() { return sz_-(BRHDRSIZE+BRTRLSIZE); }
-
   inline int HeaderSize() { return BRHDRSIZE; }
   inline int TrailerSize() { return BRTRLSIZE; }
 
   // Acces differentes zone memoire
-  inline Byte* Data() { return dst_+BRHDRSIZE; }
-  inline Byte* Header() { return dst_; }
-  inline Byte* Trailer() { return (dst_+sz_-BRTRLSIZE); }
+  inline Byte* Data() { return dst_+BRHDRSIZE+OFFSET; }
+  inline Byte* Data1() { return dst_+BRHDRSIZE+OFFSET; }
+  inline Byte* Data2() { return dst_+BRHDRSIZE+(DataSize()/2)+OFFSET; }
+  inline Byte* Header() { return dst_+OFFSET; }
+  inline Byte* Trailer() { return (dst_+sz_-BRTRLSIZE+OFFSET); }
   
   // Valeurs differentes zones HDR/TRL
-  inline UInt64 HDRMarker() {return *((UInt64*)dst_);}
-  inline UInt64 TRLMarker() {return *((UInt64*)(dst_+sz_-BRTRLSIZE));}
-  inline UInt64 TimeTag() {return *((UInt64*)(dst_+BRTMTAGOFF));}
+  inline UInt32 HDRMarker() {return *((UInt32*)(dst_+OFFSET));}
+  inline UInt32 TRLMarker() {return *((UInt32*)(dst_+(sz_-BRTRLSIZE+OFFSET)));}
+  inline UInt16 ModeAcq()   {return *((UInt16*)(dst_+(BRMODACQOFF+OFFSET)));}
+  inline UInt16 ChanId()    {return (( *((UInt16*)(dst_+(BRCHANIDOFF+OFFSET))) & 0x1800)>> 12) ;}
+  inline UInt16 ChipId()    {return (( *((UInt16*)(dst_+(BRCHANIDOFF+OFFSET))) & 0xC00)>> 10) ;}
+
+  inline UInt32 TimeTag1()   {return *((UInt32*)(dst_+(BRTMTAGOFF+OFFSET)));}
+  inline UInt32 FrameCounter()   {return ((*((UInt32*)(dst_+(BRFRCPTOFF+OFFSET))) &0xFFFF0000) >> 16);}
+  inline UInt32 TimeTag2() {return (*((UInt32*)(dst_+(BRFRCPTOFF+OFFSET))) &0xFFFF);}
+
+  inline UInt32 PaqId()     {return *((UInt32*)(dst_+(BRPKTIDOFF+OFFSET)));}
+  inline UInt16 PaqLen()    {return *((UInt16*)(dst_+(BRPKTLENOFF+OFFSET)));}
+
+
+  // inline unsigned short PositionChariot() {return *((unsigned short*)(dst_+BRPCOFF+OFFSET));}
 
   // pour faire un print de la structure
   void Print(ostream & os, int nelt=8, bool prht=true);
+  UInt16  ChannelID();
+  UInt16  ModeAcquisition();
 
-  // protected:
+  // fonction appelee par le constructeur pour reordonner les donnees FFT 
+  static void ReorderFFTData(Byte* src, Byte* dst, int sz);
+  static void ReorderFFTData32(Byte* src, Byte* dst, int sz);
+  static void ReorderFFTDataNoSwap(Byte* src, Byte* dst, int sz);
+  static const char* FmtConvToString(BRDataFmtConv fgswap);
+// protected:
   // donnees membres
   int sz_; //taille du paquet 
@@ -54,3 +151,24 @@
 };
 
+// --------------------------------------------------------------------------
+// Classe pour effectuer des verifications d'integrite sur les paquets/frames
+// --------------------------------------------------------------------------
+
+class BRPaqChecker {
+public: 
+  BRPaqChecker();
+  ~BRPaqChecker();
+  // Verifie le paquet, renvoie true si OK
+  bool Check(BRPaquet& paq);
+  // Imprime le compte de paquets ... 
+  ostream & Print(ostream& os);
+
+  unsigned long long totnframes;    // Nombre totale de frames/paquets traites 
+  unsigned long long  nframeok;     // Nombre totale de frames/paquets avec HDR/TRL OK
+  unsigned long long lostframes;    // Nombre totale de frames/paquets perdus 
+  unsigned int frclst;         // derniere valeur du frame-counter 
+};
+
 #endif
+ 
+ 
Index: /trunk/AddOn/TAcq/makefile
===================================================================
--- /trunk/AddOn/TAcq/makefile	(revision 3591)
+++ /trunk/AddOn/TAcq/makefile	(revision 3592)
@@ -1,9 +1,9 @@
 include $(SOPHYABASE)/include/sophyamake.inc
 
-all : traidio  tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits mfits2spec tsok sigana
+all : traidio  tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits mfits2spec tsok 
 
 clean :
 	rm *.o traidio tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits 
-	rm mfits2spec tsok sigana *.ppf *.fits 
+	rm mfits2spec tsok *.ppf *.fits 
 
 ########################################################
@@ -46,14 +46,9 @@
 
 ##   --------------
-sigana : sigana.o sigana.o
-	$(CXXLINK) -o sigana sigana.o minifits.o  $(SOPHYAEXTSLBLIST)
 
-sigana.o : sigana.cc minifits.h
-	$(CXXCOMPILE) -o sigana.o sigana.cc
+mfits2spec : mfits2spec.o minifits.o brpaqu.o 
+	$(CXXLINK) -o mfits2spec mfits2spec.o minifits.o brpaqu.o $(SOPHYAEXTSLBLIST)
 
-mfits2spec : mfits2spec.o minifits.o
-	$(CXXLINK) -o mfits2spec mfits2spec.o minifits.o  $(SOPHYAEXTSLBLIST)
-
-mfits2spec.o : mfits2spec.cc minifits.h
+mfits2spec.o : mfits2spec.cc minifits.h brpaqu.h 
 	$(CXXCOMPILE) -o mfits2spec.o mfits2spec.cc
 
Index: /trunk/AddOn/TAcq/mfits2spec.cc
===================================================================
--- /trunk/AddOn/TAcq/mfits2spec.cc	(revision 3591)
+++ /trunk/AddOn/TAcq/mfits2spec.cc	(revision 3592)
@@ -2,4 +2,11 @@
 #include "sopnamsp.h"
 #include "machdefs.h"
+
+/* ------------------------------------------------------------------ 
+   Programme de calcul de spectre moyenne a partir des fichiers fits  
+   d'acquisition de BAORadio - donnees brutes (non FFT)
+   R. Ansari, C. Magneville
+   V1 : Juillet 2008  , V2 : Avril 2009
+   ------------------------------------------------------------------ */
 
 // include standard c/c++
@@ -26,18 +33,27 @@
 
 
-// include mini-fits lib 
+// include mini-fits lib , et structure paquet BAORadio
 #include "minifits.h"
-
-
-inline r_4 Zmod2(complex<r_4> z) 
-{ return (z.real()*z.real()+z.imag()*z.imag()); }
-
+#include "brpaqu.h"
+
+//---- Declaration des fonctions de calcul ----
+// Fonction d'analyse 1ere version, pas d'entete ds le fichier, 1 voie
+int ana_data_0(vector<string>& infiles, string& outfile);
+// Fonction d'analyse 2eme version , 1 voie / paquet
+int ana_data_1(vector<string>& infiles, string& oufile);
+// Fonction d'analyse 2eme version , 2 voies / paquet
+int ana_data_2(vector<string>& infiles, string& oufile);
+
+//----------------------------------------------------
+//----------------------------------------------------
 int main(int narg, char* arg[])
 {
-  if (narg < 2) {
-    cout << " Usage: mfits2spec file1.fits [file2.fits ...] " << endl;
+  if (narg < 4) {
+    cout << " ---Calcul spectres moyennes a partir de fits BAORadio " << endl;
+    cout << " Usage: mfits2spec ACT OutPPF file1 [file2 file3 ...] " << endl;
+    cout << " ACT=-0,-1,-2 ==> 0: Nancay-Juil2008, - 1,2 : 1/2 voies / paquet " << endl;
+    cout << " OutPPF : Output PPF file name, file1,file2 ... Input FITS files " << endl;  
     return 1;
   }
-  cout << " ---------- mfits2spec.cc Start ------------- " << endl;
 
   TArrayInitiator  _inia;
@@ -45,47 +61,14 @@
   int rc = 0;
   try {
-  	ResourceUsage resu;
-  	TVector<float> spectre;
-  	sa_size_t nzm = 0;   // Nb de spectres moyennes
-    for(int ifile=1; ifile<narg; ifile++) {
-      string ffname = arg[ifile];
-// -------------- Lecture de bytes      
-      cout << ifile <<"-Ouverture/lecture fichier " << ffname << endl;
-      MiniFITSFile mff(ffname, MF_Read);
-      cout << "... Type=" << mff.DataTypeToString() << " NAxis1=" << mff.NAxis1() 
-	   << " NAxis2=" << mff.NAxis2() << endl;
-      if (mff.DataType() != MF_Byte) {
-        cout << " PB : DataType!=MF_Byte --> skipping " << endl;
-      }
-      size_t sx = mff.NAxis1(); 
-      size_t sy = mff.NAxis2();
-
-      Byte* data = new Byte[sx];
-      TVector<r_4> vx(sx);
-      TVector< complex<r_4> > cfour;
-      FFTPackServer ffts;
-      
-      for(int j=0; j<sy; j++) {
-	    mff.ReadB(data, sx, j*sx);
-        // On convertit en float 
-        for(sa_size_t ix=0; ix<vx.Size(); ix++)  vx(ix) = (r_4)(data[ix]);
-        // On fait le FFT
-        ffts.FFTForward(vx, cfour);
-        if (!spectre.IsAllocated())  spectre.SetSize(cfour.Size());
-        
-        // On cumule les modules carres
-        for(sa_size_t jf=1; jf<spectre.Size(); jf++) 
-          spectre(jf) += Zmod2(cfour(jf)); 
-        nzm++;
-
-//	cout << " j=" << j << " data[0...3]=" << (int)data[0] << " , " 
-//	     << (int)data[1] << " , " <<  (int)data[2] << endl;
-      }
-      cout << "---- FIN lecture " << ffname << endl;      
-    }   
-    cout << "---- Ecriture spectre moyenne ds mspectre.ppf " << endl;      
-    spectre /= (r_4)(nzm);
-    POutPersist po("mspectre.ppf");
-    po << spectre;
+    string act = arg[1];
+    string outppf = arg[2];
+    vector<string> infiles;
+    for(int i=3; i<narg; i++) infiles.push_back(arg[i]);
+    cout << " ---------- mfits2spec.cc Start - ACT= " << act << " ------------- " << endl;
+    ResourceUsage resu;
+    if (act == "-0") ana_data_0(infiles, outppf);
+    else if (act == "-1") ana_data_1(infiles, outppf);
+    else if (act == "-2") ana_data_2(infiles, outppf);
+    else cout << " mfits2spec.cc / Bad argument ACT=" << act << " -> exit" << endl;
     cout << resu ; 
   }
@@ -109,2 +92,212 @@
 
 }
+
+inline r_4 Zmod2(complex<r_4> z) 
+{ return (z.real()*z.real()+z.imag()*z.imag()); }
+
+/*--Nouvelle-Fonction--*/
+int ana_data_0(vector<string>& infiles, string& outfile)
+{
+  TVector<float> spectre;
+  sa_size_t nzm = 0;   // Nb de spectres moyennes
+  for(int ifile=0; ifile<infiles.size(); ifile++) {
+    string ffname = infiles[ifile];
+// -------------- Lecture de bytes      
+    cout << ifile <<"-Ouverture/lecture fichier " << ffname << endl;
+    MiniFITSFile mff(ffname, MF_Read);
+    cout << "... Type=" << mff.DataTypeToString() << " NAxis1=" << mff.NAxis1() 
+	 << " NAxis2=" << mff.NAxis2() << endl;
+    if (mff.DataType() != MF_Byte) {
+      cout << " PB : DataType!=MF_Byte --> skipping " << endl;
+    }
+    size_t sx = mff.NAxis1(); 
+    size_t sy = mff.NAxis2();
+
+    Byte* data = new Byte[sx];
+    TVector<r_4> vx(sx);
+    TVector< complex<r_4> > cfour;
+    FFTPackServer ffts;
+      
+    for(int j=0; j<sy; j++) {
+      mff.ReadB(data, sx, j*sx);
+      // On convertit en float 
+      for(sa_size_t ix=0; ix<vx.Size(); ix++)  vx(ix) = (r_4)(data[ix]);
+      // On fait le FFT
+      ffts.FFTForward(vx, cfour);
+      if (!spectre.IsAllocated())  spectre.SetSize(cfour.Size());
+        
+      // On cumule les modules carres
+      for(sa_size_t jf=1; jf<spectre.Size(); jf++) 
+        spectre(jf) += Zmod2(cfour(jf)); 
+      nzm++;
+
+//	cout << " j=" << j << " data[0...3]=" << (int)data[0] << " , " 
+//	     << (int)data[1] << " , " <<  (int)data[2] << endl;
+      }
+    cout << "---- FIN lecture " << ffname << endl;      
+    delete[] data;
+  }   
+  cout << "---- Ecriture spectre moyenne ds " << outfile << endl;      
+  spectre /= (r_4)(nzm);
+  POutPersist po(outfile);
+  po << spectre;
+  return 0;
+}
+
+/*--Nouvelle-Fonction--*/
+int ana_data_1(vector<string>& infiles, string& outfile)
+{
+  TVector<float> spectre;
+  float freq0 = 0;  
+  int paqsz = 0;
+  int nfileok;
+  sa_size_t nzm = 0;   // Nb de spectres moyennes
+  Byte* data = NULL;
+  FFTPackServer ffts;
+  for(int ifile=0; ifile<infiles.size(); ifile++) {
+    string ffname = infiles[ifile];
+// -------------- Lecture de bytes      
+    cout << "ana_data_1[" << ifile <<"]Ouverture/lecture fichier " << ffname << endl;
+    MiniFITSFile mff(ffname, MF_Read);
+    cout << "... Type=" << mff.DataTypeToString() << " NAxis1=" << mff.NAxis1() 
+	 << " NAxis2=" << mff.NAxis2() << endl;
+    if (mff.DataType() != MF_Byte) {
+      cout << " PB : DataType!=MF_Byte --> skipping " << endl;
+      continue;
+    }
+// Les fichier FITS contiennent l'entet (24 bytes), mais pas le trailer (16 bytes) ...
+    if (paqsz == 0)  {  // premier passage, on fixe la taille de paquet et on alloue le buffer
+      paqsz = mff.NAxis1()+16;
+      data = new Byte[paqsz];
+      for(int ib=0; ib<paqsz; ib++) data[ib]=0;
+    }
+    else {
+      if (paqsz != mff.NAxis1()+16) {
+      cout << " PB : paqsz=" << paqsz << " != mff.NAxis1()+16 --> skipping " << endl;
+      continue;
+      }
+    }
+    size_t sx = mff.NAxis1(); 
+    size_t sy = mff.NAxis2();
+    BRPaquet paq(NULL, data, paqsz);
+    TVector<r_4> vx(paq.DataSize());
+    TVector< complex<r_4> > cfour;
+      
+    for(int j=0; j<sy; j++) {
+      mff.ReadB(data, sx, j*sx);
+      // On convertit en float 
+      for(sa_size_t ix=0; ix<vx.Size(); ix++)  vx(ix) = (r_4)(paq.Data1()[ix])-127.5;
+      // On fait le FFT
+      ffts.FFTForward(vx, cfour);
+      if (!spectre.IsAllocated())  spectre.SetSize(cfour.Size());
+        
+      // On cumule les modules carres  - en sautant la frequence zero 
+      for(sa_size_t jf=1; jf<spectre.Size(); jf++) 
+        spectre(jf) += Zmod2(cfour(jf)); 
+      nzm++;  freq0 += cfour(0).real();
+      }
+    nfileok++;
+    cout << "---- FIN lecture " << ffname << " NFileOK=" << nfileok << endl;      
+  }   
+  if (data) delete[] data;
+  if (nzm <= 0) {
+    cout << " ana_data_1/ERROR : nzm=" << nzm << " spectres moyennes !" << endl;
+    return nzm;
+  } 
+  cout << "---- Ecriture spectre moyenne ds " << outfile  << endl;      
+  spectre /= (r_4)(nzm);
+  spectre.Info().Comment() = " SpectreMoyenne (Moyenne module^2) ";
+  spectre.Info()["NMOY"] = nzm; // Nombre de spectres moyennes
+  spectre.Info()["Freq0"] = freq0;
+  POutPersist po(outfile);
+  po << PPFNameTag("specV1") << spectre;
+  return nfileok;
+}
+
+/*--Nouvelle-Fonction--*/
+int ana_data_2(vector<string>& infiles, string& outfile)
+{
+  TVector<float> specV1, specV2;
+  TVector< complex<float> > cxspecV12;
+  float freq0v1 = 0;  
+  float freq0v2 = 0;  
+  int paqsz = 0;
+  int nfileok;
+  sa_size_t nzm = 0;   // Nb de spectres moyennes
+  Byte* data = NULL;
+  FFTPackServer ffts;
+  for(int ifile=0; ifile<infiles.size(); ifile++) {
+    string ffname = infiles[ifile];
+// -------------- Lecture de bytes      
+    cout << "ana_data_2[" << ifile <<"]Ouverture/lecture fichier " << ffname << endl;
+    MiniFITSFile mff(ffname, MF_Read);
+    cout << "... Type=" << mff.DataTypeToString() << " NAxis1=" << mff.NAxis1() 
+	 << " NAxis2=" << mff.NAxis2() << endl;
+    if (mff.DataType() != MF_Byte) {
+      cout << " PB : DataType!=MF_Byte --> skipping " << endl;
+      continue;
+    }
+// Les fichier FITS contiennent l'entet (24 bytes), mais pas le trailer (16 bytes) ...
+    if (paqsz == 0)  {  // premier passage, on fixe la taille de paquet et on alloue le buffer
+      paqsz = mff.NAxis1()+16;
+      cout << " ana_data_2/ Allocating data , PaqSz=" << paqsz << endl;
+      data = new Byte[paqsz];
+      for(int ib=0; ib<paqsz; ib++) data[ib]=0;
+    }
+    else {
+      if (paqsz != mff.NAxis1()+16) {
+      cout << " PB : paqsz=" << paqsz << " != mff.NAxis1()+16 --> skipping " << endl;
+      continue;
+      }
+    }
+    size_t sx = mff.NAxis1(); 
+    size_t sy = mff.NAxis2();
+    BRPaquet paq(NULL, data, paqsz);
+    TVector<r_4> vx1(paq.DataSize()/2);
+    TVector<r_4> vx2(paq.DataSize()/2);
+    TVector< complex<r_4> > cfour1,cfour2;
+      
+    for(int j=0; j<sy; j++) {
+      mff.ReadB(data, sx, j*sx);
+     // if (j%50 == 0) cout << " *DBG* mff.ReadB() , j=" << j << endl;
+     // On convertit en float 
+      for(sa_size_t ix=0; ix<vx1.Size(); ix++)  vx1(ix) = (r_4)(paq.Data1()[ix])-127.5;
+      for(sa_size_t ix=0; ix<vx2.Size(); ix++)  vx2(ix) = (r_4)(paq.Data2()[ix])-127.5;
+      // On fait le FFT
+      ffts.FFTForward(vx1, cfour1);
+      ffts.FFTForward(vx2, cfour2);
+      if (!specV1.IsAllocated())  specV1.SetSize(cfour1.Size());
+      if (!specV2.IsAllocated())  specV2.SetSize(cfour2.Size());
+      if (!cxspecV12.IsAllocated())  cxspecV12.SetSize(cfour1.Size());
+        
+      // On cumule les modules carres  - en sautant la frequence zero 
+      for(sa_size_t jf=1; jf<specV1.Size(); jf++) {
+        specV1(jf) += Zmod2(cfour1(jf)); 
+        specV2(jf) += Zmod2(cfour2(jf)); 
+        cxspecV12(jf) += cfour1(jf)*cfour2(jf);
+      }
+      nzm++;  freq0v1 += cfour1(0).real();  freq0v2 += cfour2(0).real(); 
+      }
+    nfileok++;
+    cout << "---- FIN lecture " << ffname << " NFileOK=" << nfileok << endl;      
+  }  
+  if (data) delete[] data;
+  if (nzm <= 0) {
+    cout << " ana_data_2/ERROR : nzm=" << nzm << " spectres moyennes !" << endl;
+    return nzm;
+  } 
+  cout << "---- Ecriture spectre moyenne ds " << outfile  << endl;      
+  specV1 /= (r_4)(nzm);
+  specV2 /= (r_4)(nzm);
+  cxspecV12 /= complex<r_4>((r_4)(nzm),0.);
+  specV1.Info().Comment() = " SpectreMoyenne (Moyenne module^2) - Voie 1 (/2)";
+  specV2.Info().Comment() = " SpectreMoyenne (Moyenne module^2) - Voie 2 (/2)";
+  specV1.Info()["NMOY"] = specV2.Info()["NMOY"] = nzm; // Nombre de spectres moyennes
+  specV1.Info()["Freq0"] = freq0v1;
+  specV2.Info()["Freq0"] = freq0v2;
+  POutPersist po(outfile);
+  po << PPFNameTag("specV1") << specV1;
+  po << PPFNameTag("specV2") << specV2;
+  po << PPFNameTag("cxspecV12") << cxspecV12;
+  return 0;
+}
Index: /trunk/AddOn/TAcq/minifits.h
===================================================================
--- /trunk/AddOn/TAcq/minifits.h	(revision 3591)
+++ /trunk/AddOn/TAcq/minifits.h	(revision 3592)
@@ -18,4 +18,5 @@
   explicit MiniFITSException(const char * m) { msg = m; }
   explicit MiniFITSException(const string& m) { msg = m; }
+  virtual ~MiniFITSException() { } 
   virtual string const& Msg() const  {return msg;}
  private:
