Index: /trunk/AddOn/TAcq/brproc.cc
===================================================================
--- /trunk/AddOn/TAcq/brproc.cc	(revision 3644)
+++ /trunk/AddOn/TAcq/brproc.cc	(revision 3645)
@@ -27,16 +27,18 @@
 //---------------------------------------------------------------
 
+/* --Methode-- */
 BRProcARaw2C::BRProcARaw2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean, 
-                           uint_4 step, uint_4 nmax, bool fgnotrl)
+                           uint_4 nmax, bool fgnotrl, int card)
   :  memgr(mem) 
 {
   nmax_ = nmax;	
   nmean_ = nmean;
-  step_ = step;
   stop_ = false;	
   path_ = path;	
   fgnotrl_ = fgnotrl;
-}
-
+  card_ = card;
+}
+
+/* --Methode-- */
 void BRProcARaw2C::Stop()
 {
@@ -49,4 +51,10 @@
 { return (z.real()*z.real()+z.imag()*z.imag()); }
 
+static inline string card2name_(int card)
+{
+  if (card==2) return " (Chan3,4) ";
+  else return " (Chan1,2) ";
+}
+/* --Methode-- */
 void BRProcARaw2C::run()
 {
@@ -61,5 +69,5 @@
 
     cout << " BRProcARaw2C::run() - Starting " << ts << " NMaxMemZones=" << nmax_ 
-	 << " NMean=" << nmean_ << " Step=" << step_ << endl;	
+	 << " NMean=" << nmean_ << card2name_(card_) << endl;	
     cout << " BRProcARaw2C::run()... - Output Data Path: " << path_ << endl;
     char fname[512];
@@ -106,13 +114,13 @@
       }
 
-      for(uint_4 i=0; i<memgr.NbPaquets(); i+=step_) {
+      for(uint_4 i=0; i<memgr.NbPaquets(); i++) {
   	    BRPaquet paq(NULL, buff+i*paqsz, paqsz); 
         if (!pcheck.Check(paq)) continue;   // on ne traite que les paquets OK
 
 // Traitement voie 1  	    
-  	    for(sa_size_t j=0; j<vx.Size(); j++) 
-  	      vx(j) = (r_4)(*(paq.Data1()+j))-127.5;
+  	  for(sa_size_t j=0; j<vx.Size(); j++) 
+  	    vx(j) = (r_4)(*(paq.Data1()+j))-127.5;
 //        fftwf_complex* coeff1 = (fftwf_complex*)(procbuff+i*procpaqsz);
-  	    fftwf_execute(plan1); 
+  	  fftwf_execute(plan1); 
 //        complex<r_4>* zp1 = (complex<r_4>*)(coeff1);
 //        ffts.FFTForward(vx, cfour1);
@@ -121,8 +129,8 @@
         memcpy(procbuff+i*procpaqsz, cfour1.Data(), sizeof(complex<r_4>)*cfour1.Size());
 // Traitement voie 2  	    
-   	    for(sa_size_t j=0; j<vx.Size(); j++) 
- 	      vx(j) = (r_4)(*(paq.Data2()+j))-127.5;
-
-  	    fftwf_execute(plan2); 
+   	for(sa_size_t j=0; j<vx.Size(); j++) 
+ 	  vx(j) = (r_4)(*(paq.Data2()+j))-127.5;
+
+  	fftwf_execute(plan2); 
 
         for(sa_size_t j=0; j<spectreV2.Size(); j++) 
@@ -151,7 +159,15 @@
     	sprintf(fname,"%s_%d.ppf",path_.c_str(),(int)ifile);
         POutPersist po(fname);
-        po << PPFNameTag("specV1") << spectreV1; 
-        po << PPFNameTag("specV2") << spectreV2; 
-        po << PPFNameTag("visiV12") << visiV12; 
+        string tag1="specV1";
+        string tag2="specV2";
+        string tag12="visiV12";
+        if (card_==2) {
+          tag1 = "specV3";
+          tag2 = "specV4";
+          tag12="visiV34";
+        }
+        po << PPFNameTag(tag1) << spectreV1; 
+        po << PPFNameTag(tag2) << spectreV2; 
+        po << PPFNameTag(tag12) << visiV12; 
 	    }
         spectreV1 = (r_4)(0.);
@@ -161,10 +177,11 @@
 //        ts.SetNow();
 //        filog << ts << " :  proc file  " << fname << endl;		       
-        cout << " BRProcARaw2C::run() created file  " << fname << endl;
+        cout << " BRProcARaw2C::run() created file  " << fname << card2name_(card_) << endl;
       }   
       
       memgr.FreeMemZone(mid, MemZS_ProcA);
     }  // Fin de boucle sur les zones a traiter 
-  cout << " ------------------  BRProcARaw2C::run() END ----------------- " << endl;
+  cout << " ------------  BRProcARaw2C::run() END " << card2name_(card_) 
+       << " ------------ " << endl;
   ts.SetNow();
   tm.SplitQ();
@@ -173,5 +190,5 @@
        << " ProcDataOut=" <<  totnbytesout/(1024*1024) << " MB" << endl;    
   cout << pcheck;
-  cout << " BRProcARaw2C::run()/Timing: \n"; 
+  cout << " BRProcARaw2C::run()/Timing: " << card2name_(card_) << endl; 
   tm.Print();
   cout << " ---------------------------------------------------------- " << endl;
@@ -192,5 +209,192 @@
 }   
 
-
-
-
+//---------------------------------------------------------------------
+// Classe thread de traitement 2 x 2 voies/frames (Apres BRProcARaw2C)
+//---------------------------------------------------------------------
+
+/* --Methode-- */
+BRProcBRaw4C::BRProcBRaw4C(RAcqMemZoneMgr& mem1, RAcqMemZoneMgr& mem2, 
+                           string& path, uint_4 nmean, uint_4 nmax, bool fgnotrl)
+  :  memgr1(mem1), memgr2(mem2) 
+{
+  nmax_ = nmax;	
+  nmean_ = nmean;
+  stop_ = false;	
+  path_ = path;	
+  fgnotrl_ = fgnotrl;
+}
+
+/* --Methode-- */
+void BRProcBRaw4C::Stop()
+{
+ stop_=true;
+ // cout <<" BRProcBRaw4C::Stop ... > STOP " << endl;
+}
+
+
+/* --Methode-- */
+void BRProcBRaw4C::run()
+{
+  setRC(1);	
+  try {
+    Timer tm("BRProcBRaw4C", false);
+    TimeStamp ts; 
+    BRPaqChecker pcheck1(~fgnotrl_);  // Verification/comptage des paquets 
+    BRPaqChecker pcheck2(~fgnotrl_);  // Verification/comptage des paquets 
+
+    size_t totnbytesout = 0;
+    size_t totnbytesproc = 0;
+
+    cout << " BRProcBRaw4C::run() - Starting " << ts << " NMaxMemZones=" << nmax_ 
+	 << " NMean=" << nmean_ << endl;	
+    cout << " BRProcBRaw4C::run()... - Output Data Path: " << path_ << endl;
+
+    uint_4 paqsz = memgr1.PaqSize();
+    uint_4 procpaqsz = memgr1.ProcPaqSize();
+    if ((paqsz != memgr2.PaqSize())||(procpaqsz!= memgr2.ProcPaqSize())) {
+      cout << "BRProcBRaw4C::run()/ERROR : different paquet size -> stop \n ...(PaqSz1="
+           << paqsz << " Sz2=" << memgr2.PaqSize() << " ProcPaqSz1=" 
+           << procpaqsz << " Sz2=" << memgr2.ProcPaqSize() << " )" << endl;
+      setRC(9);	
+      return;   
+    }
+
+    TVector< complex<r_4> > cfour;  // composant TF
+    BRPaquet pq(NULL, NULL, paqsz); 
+    TVector<r_4> vx(pq.DataSize()/2);
+    vx = (r_4)(0.);
+    FFTPackServer ffts;
+    ffts.FFTForward(vx, cfour);
+    
+    TVector< complex<r_4> > visiV13( cfour.Size() );
+    TVector< complex<r_4> > visiV14( cfour.Size() );
+    TVector< complex<r_4> > visiV23( cfour.Size() );
+    TVector< complex<r_4> > visiV24( cfour.Size() );
+
+    uint_4 nzm = 0;
+    uint_4 totnoksfc = 0;
+    uint_4 totnokpaq = 0;
+    uint_4 totnpaq = 0;
+    uint_4 ifile = 0;
+    for (uint_4 kmz=0; kmz<nmax_; kmz++) {
+      uint_4 noksfc = 0;
+      uint_4 nokpaq = 0;
+      if (stop_) break;
+      int mid1 = memgr1.FindMemZoneId(MemZA_ProcB);
+      Byte* buff1 = memgr1.GetMemZone(mid1);
+      if (buff1 == NULL) {
+         cout << " BRProcBRaw4C::run()/ERROR memgr.GetMemZone(" << mid1 << ") -> NULL" << endl;
+  	     break;		
+      }
+      Byte* procbuff1 = memgr1.GetProcMemZone(mid1);
+      if (procbuff1 == NULL) {
+  	    cout << " BRProcBRaw4C::run()/ERROR memgr.GetProcMemZone(" << mid1 << ") -> NULL" << endl;
+        break;	
+      }
+      int mid2 = memgr2.FindMemZoneId(MemZA_ProcB);
+      Byte* buff2 = memgr2.GetMemZone(mid2);
+      if (buff1 == NULL) {
+         cout << " BRProcBRaw4C::run()/ERROR memgr.GetMemZone(" << mid2 << ") -> NULL" << endl;
+  	     break;		
+      }
+      Byte* procbuff2 = memgr2.GetProcMemZone(mid2);
+      if (procbuff2 == NULL) {
+  	    cout << " BRProcBRaw4C::run()/ERROR memgr.GetProcMemZone(" << mid2 << ") -> NULL" << endl;
+        break;	
+      }
+      uint_4 i1,i2;
+      i1=i2=0;
+      while((i1<memgr1.NbPaquets())&&(i2<memgr2.NbPaquets())) {
+	BRPaquet paq1(NULL, buff1+i1*paqsz, paqsz); 
+	BRPaquet paq2(NULL, buff2+i2*paqsz, paqsz); 
+        totnpaq++;
+//        cout << " DBG["<<kmz<<"] i1,i2=" << i1 <<","<<i2<<" FC1,FC2=" <<paq1.FrameCounter()
+//<<","<<paq2.FrameCounter()<<endl;
+        // on ne traite que les paquets OK
+        if (!pcheck1.Check(paq1)) { i1++; continue; } 
+        if (!pcheck2.Check(paq2)) { i2++; continue; }
+        nokpaq++;
+        if (paq1.FrameCounter()<paq2.FrameCounter()) { i1++; continue; }  
+        if (paq2.FrameCounter()<paq1.FrameCounter()) { i2++; continue; }  
+//        cout << " DBG["<<kmz<<"]OKOK i1,i2=" << i1 <<","<<i2<<" FC1,FC2=" <<paq1.FrameCounter()
+// <<","<<paq2.FrameCounter()<<endl;
+
+        // Les deux framecounters sont identiques ...
+        noksfc++;
+        complex<r_4>* zp1 = (complex<r_4>*)(procbuff1+i1*procpaqsz);
+        complex<r_4>* zp2 = (complex<r_4>*)(procbuff1+i1*procpaqsz+procpaqsz/2);
+        complex<r_4>* zp3 = (complex<r_4>*)(procbuff2+i2*procpaqsz);
+        complex<r_4>* zp4 = (complex<r_4>*)(procbuff2+i2*procpaqsz+procpaqsz/2);
+        for(sa_size_t j=0; j<visiV13.Size(); j++) { 
+          visiV13(j)+=zp1[j]*conj(zp3[j]);
+          visiV14(j)+=zp1[j]*conj(zp4[j]);
+          visiV23(j)+=zp2[j]*conj(zp3[j]);
+          visiV24(j)+=zp2[j]*conj(zp4[j]);
+        }
+        nzm++;  i1++; i2++;
+        totnbytesproc += 2*paq1.DataSize();
+      } // Fin de boucle sur les paquets d'une zone
+      if ((nzm >= nmean_) || ((kmz==(nmax_-1))&&(nzm>1))) {
+        visiV13 /= complex<r_4>((r_4)nzm, 0.);
+        visiV14 /= complex<r_4>((r_4)nzm, 0.);
+        visiV23 /= complex<r_4>((r_4)nzm, 0.);
+        visiV24 /= complex<r_4>((r_4)nzm, 0.);
+        visiV13.Info()["NPaqMoy"] = nzm;
+        visiV14.Info()["NPaqMoy"] = nzm;
+        visiV23.Info()["NPaqMoy"] = nzm;
+        visiV24.Info()["NPaqMoy"] = nzm;
+        char fname[512];
+	{
+    	sprintf(fname,"%s_%d.ppf",path_.c_str(),(int)ifile);
+        POutPersist po(fname);
+        po << PPFNameTag("visiV13") << visiV13; 
+        po << PPFNameTag("visiV14") << visiV14; 
+        po << PPFNameTag("visiV23") << visiV23; 
+        po << PPFNameTag("visiV24") << visiV24; 
+	}
+        visiV13 = complex<r_4>(0., 0.);
+        visiV14 = complex<r_4>(0., 0.);
+        visiV23 = complex<r_4>(0., 0.);
+        visiV24 = complex<r_4>(0., 0.);
+        nzm = 0;  
+//        ts.SetNow();
+//        filog << ts << " :  proc file  " << fname << endl;		       
+        cout << " BRProcBRaw4C::run() created file  " << fname << endl;
+      }   
+      memgr1.FreeMemZone(mid1, MemZS_ProcB);
+      memgr2.FreeMemZone(mid2, MemZS_ProcB);
+      double okfrac = (nokpaq>1)?((double)noksfc/(double)nokpaq*100.):0.;
+      cout << "BRProcBRaw2C ["<<kmz<<"] NOKPaq=" << nokpaq << " NSameFC=" << noksfc 
+           << " (" << okfrac << " %)" << endl;
+      totnokpaq += nokpaq;
+      totnoksfc += noksfc;
+    }  // Fin de boucle sur les zones a traiter 
+    cout << " ------------------  BRProcBRaw4C::run() END ----------------- " << endl;
+    ts.SetNow();
+    tm.SplitQ();
+    cout << "  TotalProc= " << totnbytesproc/(1024*1024) << " MBytes, rate= " 
+         << (double)(totnbytesproc)/1024./tm.PartialElapsedTimems() << " MB/s" << endl;
+    double totokfrac = (totnokpaq>1)?((double)totnoksfc/(double)totnokpaq*100.):0.;
+    cout << " NOkPaq1,2=" << totnokpaq << " /TotNPaq=" << totnpaq << " TotNSameFC=" 
+         << totnoksfc << " (" << totokfrac << " %)" << endl;
+//  cout << pcheck1;
+//  cout << pcheck2;
+    cout << " BRProcBRaw4C::run()/Timing: \n"; 
+    tm.Print();
+    cout << " ---------------------------------------------------------- " << endl;
+}
+  catch (PException& exc) {
+    cout << " BRProcBRaw4C::run()/catched PException " << exc.Msg() << endl;
+    setRC(3);	
+    return; 
+  }
+  catch(...) {
+    cout << " BRProcBRaw4C::run()/catched unknown ... exception " << endl;
+    setRC(4);	
+    return; 
+  }
+  setRC(0);
+  return;
+}   
+
+
Index: /trunk/AddOn/TAcq/brproc.h
===================================================================
--- /trunk/AddOn/TAcq/brproc.h	(revision 3644)
+++ /trunk/AddOn/TAcq/brproc.h	(revision 3645)
@@ -25,6 +25,6 @@
 class BRProcARaw2C : public ZThread {
 public:	
-  BRProcARaw2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=1, 
-               uint_4 step=1, uint_4 nmax=100, bool fgnotrl=false);
+  BRProcARaw2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=10, 
+               uint_4 nmax=100, bool fgnotrl=false, int card=1);
   virtual void run(); 
   void Stop();
@@ -34,5 +34,25 @@
   bool stop_;  
   uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
-  uint_4 step_;  // 1/step_ frame traite ds chaque bloc
+  uint_4 nmean_;  // Nombre de blocs pour le calcul des moyennes 
+  string path_;  
+  bool fgnotrl_;   // if true, don't check packet trailer - when using pre-june fits files
+  int card_;   // Numeros de voies 2*card_-1, 2*card_
+};
+
+//---------------------------------------------------------------------
+// Classe thread de traitement 2 x 2 voies/frames (Apres BRProcARaw2C)
+//---------------------------------------------------------------------
+class BRProcBRaw4C : public ZThread {
+public:	
+  BRProcBRaw4C(RAcqMemZoneMgr& mem1, RAcqMemZoneMgr& mem2, string& path, 
+               uint_4 nmean=10, uint_4 nmax=100, bool fgnotrl=false);
+  virtual void run(); 
+  void Stop();
+  inline void STOP() { stop_ = true; }	
+protected:
+  RAcqMemZoneMgr& memgr1;
+  RAcqMemZoneMgr& memgr2;
+  bool stop_;  
+  uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
   uint_4 nmean_;  // Nombre de blocs pour le calcul des moyennes 
   string path_;  
@@ -41,3 +61,4 @@
 
 
+
 #endif
Index: /trunk/AddOn/TAcq/makefile
===================================================================
--- /trunk/AddOn/TAcq/makefile	(revision 3644)
+++ /trunk/AddOn/TAcq/makefile	(revision 3645)
@@ -28,8 +28,8 @@
 ## Lecture / traitement minifits multi-thread
 ##   --------------
-mcrd : mcrd.o  racqumem.o brfitsrd.o brproc.o racquproc.o brpaqu.o pciewrap.o minifits.o
-	$(CXXLINK) -o mcrd mcrd.o  racqumem.o brfitsrd.o brproc.o racquproc.o brpaqu.o minifits.o $(SOPHYAALLSLBLIST)
+mcrd : mcrd.o  racqumem.o brfitsrd.o brproc.o racquproc.o brpaqu.o racqurw.o pciewrap.o minifits.o
+	$(CXXLINK) -o mcrd mcrd.o  racqumem.o brfitsrd.o brproc.o racquproc.o brpaqu.o racqurw.o pciewrap.o minifits.o $(SOPHYAALLSLBLIST)
 
-mcrd.o : mcrd.cc brfitsrd.h racqumem.h brproc.h 
+mcrd.o : mcrd.cc brfitsrd.h racqumem.h brproc.h racqurw.h
 	$(CXXCOMPILE) -c  -o mcrd.o mcrd.cc 
 
Index: /trunk/AddOn/TAcq/mcrd.cc
===================================================================
--- /trunk/AddOn/TAcq/mcrd.cc	(revision 3644)
+++ /trunk/AddOn/TAcq/mcrd.cc	(revision 3645)
@@ -39,4 +39,5 @@
 #include "brfitsrd.h"
 #include "brproc.h"
+#include "racqurw.h"
 
 
@@ -53,19 +54,26 @@
 }
 
+//--  Parametres globaux
+static int NZones=4;
+static int NPaqinZone=128;
+static int NMean=1024;
+static int NGenZ=100;
+static int GPaqSz=16424;
+static double LossRate=0.1;
+// ----
+int Usage(bool fgshort=true);
+// Pour traitement (calcul FFT et visibilites (ProcA) 1 fibre, 2 voies RAW)
+int Proc1FRawA(string& outname, string& inpath, int jf1, int jf2, bool fgnotrl=false, 
+               bool fgrdfile=true);
+// Pour traitement (calcul FFT et visibilites (ProcA,ProcB) 2 fibre, 4 voies RAW)
+int Proc2FRawAB(string& outname, string& path1, string& path2, int jf1, int jf2, 
+                bool fgnotrl=false, bool fgrdfile=true);
+
 //----------------------------------------------------
 //----------------------------------------------------
 int main(int narg, char* arg[])
 {
-  if (narg < 4) {
-    cout << " --- Reading/Processing BAORadio FITS files" << endl;
-    cout << " Usage:  mcrd ACT OutPPF -infits DirName Imin Imax [NZones,NbPaqinZone] " << endl;
-    cout << " ACT= notrl FITS files without frame trailer \n" 
-         << " OutPPF : Output PPF file name (without .ppf)" << endl;
-    cout << " -infiles DirName Imin Imax : Input fits directory and sequence numbers \n" 
-         << "    FileNames=DirName/signalII.fits Imin<=II<=Imax \n"
-         << " - NZones,NbPaqinZone : Number of Zones and number of paquets in one zone\n" 
-         << "     of the RAcqMemZoneMgr memory manager (default = 4,128) " << endl;
-    return 1;
-  }
+  if ((narg>1)&&(strcmp(arg[1],"-h")==0))  return Usage(false);
+  if (narg<5) return Usage(true);
 
   TArrayInitiator  _inia;
@@ -74,50 +82,32 @@
   try {
     string act = arg[1];
-    string outname = arg[2];
-    vector<string> infiles;
-    if ((strcmp(arg[3],"-infits")!=0) || (narg<7)) {
-        cout << " mcrd/Error arguments - type mcrd for help" << endl;
-        return 2;
-    }
-    char nbuff[1024];
-    char* dirname = arg[4]; 
-    int imin = atoi(arg[5]);
-    int imax = atoi(arg[6]);
-    for(int ii=imin; ii<=imax; ii++) {
-      sprintf(nbuff,"%s/signal%d.fits",dirname,ii);
-      infiles.push_back(nbuff);
-    }
-    int nzones = 4;
-    int npaqz = 128;
-    if (narg>7) sscanf(arg[7],"%d,%d",&nzones,&npaqz);	
+    bool fg4c=false;  // true -> 4 channels (2 fibers)
+    bool fgrdfits=false;  // false -> Don't read fits files, generate paquets
+    bool fgnotrl=false;   // true -> fichier fits SANS Trailer de frame (< mai 2009)
+    if (act.substr(0,2)=="-4") fg4c=true;
+    if (act.substr(2)=="g")  fgrdfits=false;
+    else if (act.substr(2)=="nt")  fgnotrl=true;
+    if (fg4c && (narg<6)) return Usage(true);
+
+    string outname = arg[2];    
+    string inpath2;
+    string inpath = arg[3]; 
+    int offa=4;
+    if(fg4c) { 
+      inpath2=arg[4];    offa=5; 
+    } 
+    int imin=0;
+    int imax=0;
+    sscanf(arg[offa],"%d,%d",&imin,&imax);
+    if (narg>offa+1) sscanf(arg[offa+1],"%d,%d",&NZones,&NPaqinZone);	
+    if (narg>offa+2) NMean=atoi(arg[offa+2]);
+    if (narg>offa+3) sscanf(arg[offa+3],"%d,%d,%lg",&GPaqSz,&NGenZ,&LossRate);	
 
     cout << " ---------- mcrd.cc Start - ACT= " << act << " ------------- " << endl;
     ResourceUsage resu;
-    bool fgnotrl=false;   // fichier fits avec Trailer de frame (> mai 2009)
-    if (act=="notrl") fgnotrl=true;  // fichier fits SANS trailer 
-
-    uint_4 paqsz, npaqf;
-    DecodeMiniFitsHeader(infiles[0],paqsz, npaqf, fgnotrl); 
-
-    cout << " mcrd: NZones=" << nzones << " NbPaq=" << npaqz << "(in file=" << npaqf
-         << " ) PaqSz=" << paqsz << endl;
-         
-    RAcqMemZoneMgr mmgr(nzones, npaqz, paqsz, sizeof(complex<r_4>)*paqsz);
-    mmgr.SetFinalizedMask((uint_4)MemZS_ProcA);
-
-    BRFitsReader reader(mmgr, infiles, fgnotrl);
-    BRProcARaw2C proc(mmgr, outname, npaqf, 1, npaqf*infiles.size()/npaqz);
-
-    cout << " mcrd.cc : Starting threads (reader, proc) ... " << endl;
-    reader.start();
-    proc.start();
-    sleep(1);
-    cout << " mcrd.cc : Waiting for reader thread to finish ... " << endl;
-    reader.join();
-    cout << " mcrd.cc : Reader finished, waiting for process thread to finish ... " << endl;
-    sleep(2);
-    mmgr.Stop();
-    proc.join();
-    mmgr.Print(cout);
+    if (fg4c) 
+      rc =  Proc2FRawAB(outname, inpath, inpath2, imin, imax, fgnotrl, fgrdfits); 
+    else 
+      rc =  Proc1FRawA(outname, inpath, imin, imax, fgnotrl, fgrdfits); 
     cout << resu ; 
   }
@@ -137,6 +127,178 @@
   } 
 
-  cout << ">>>> mcrd.cc ------- FIN ----------- RC=" << rc << endl;
+  cout << ">>>> mcrd.cc ------- END ----------- RC=" << rc << endl;
   return rc;
 
 }
+
+
+
+// Pour traitement (calcul FFT et visibilites (ProcA) 1 fibre, 2 voies RAW)
+int Proc1FRawA(string& outname, string& inpath, int imin, int imax, 
+               bool fgnotrl, bool fgrdfile)
+{
+  vector<string> infiles;
+  char nbuff[1024];
+  for(int ii=imin; ii<=imax; ii++) {
+    sprintf(nbuff,"%s/signal%d.fits",inpath.c_str(),ii);
+    infiles.push_back(nbuff);
+  }
+  uint_4 nmaxz;
+  uint_4 paqsz, npaqf;
+  if (fgrdfile) {
+    DecodeMiniFitsHeader(infiles[0],paqsz, npaqf, fgnotrl); 
+    nmaxz = infiles.size()*npaqf/NPaqinZone;
+    cout << " mcrd/Proc1FRawA/ReadFits: NZones=" << NZones << " NbPaq=" << NPaqinZone 
+         << " NPaq in file=" << npaqf
+         << " PaqSz=" << paqsz << " NMaxZ=" << nmaxz << " NMean=" << NMean << endl;
+  }
+  else {
+    paqsz = GPaqSz;
+    nmaxz = NGenZ;
+    cout << " mcrd/Proc1FRawA/GeneratePaquets: NZones=" << NZones << " NbPaq=" << NPaqinZone 
+         << "  PaqSz=" << paqsz << " NMean=" << NMean << endl;
+  }
+  RAcqMemZoneMgr mmgr(NZones, NPaqinZone, paqsz, sizeof(complex<r_4>)*paqsz);
+  mmgr.SetFinalizedMask((uint_4)MemZS_ProcA);
+
+  BRFitsReader reader(mmgr, infiles, fgnotrl);
+  TestPCIWrapperNODMA pciw(paqsz,LossRate);
+  PCIEReader pcird(pciw, paqsz, paqsz, mmgr, nmaxz, BR_Copy);
+
+  outname += "/Ch12";
+  BRProcARaw2C proc(mmgr, outname, NMean, nmaxz, fgnotrl);
+
+  cout << " mcrd/Proc1FRawA: Starting threads (reader, proc) ... " << endl;
+
+  if (fgrdfile) reader.start();
+  else pcird.start();
+
+  proc.start();
+  sleep(1);
+  cout << " mcrd/Proc1FRawA: Waiting for reader thread to finish ... " << endl;
+  if (fgrdfile) reader.join();
+  else pcird.join();
+  cout << " mcrd/Proc1FRawA: Reader finished, waiting for process thread to finish ... " << endl;
+  sleep(2);
+  mmgr.Stop();
+  proc.join();
+  mmgr.Print(cout);
+  return 0;
+}
+
+
+// Pour traitement (calcul FFT et visibilites (ProcA) 1 fibre, 2 voies RAW)
+int Proc2FRawAB(string& outname, string& path1, string& path2, int imin, int imax, 
+               bool fgnotrl, bool fgrdfile)
+{
+  vector<string> infiles1;
+  vector<string> infiles2;
+  char nbuff[1024];
+  for(int ii=imin; ii<=imax; ii++) {
+    sprintf(nbuff,"%s/signal%d.fits",path1.c_str(),ii);
+    infiles1.push_back(nbuff);
+    sprintf(nbuff,"%s/signal%d.fits",path2.c_str(),ii);
+    infiles2.push_back(nbuff);
+  }
+  uint_4 nmaxz;
+  uint_4 paqsz, npaqf;
+  if (fgrdfile) {
+    DecodeMiniFitsHeader(infiles1[0],paqsz, npaqf, fgnotrl); 
+    nmaxz = infiles1.size()*npaqf/NPaqinZone;
+    cout << " mcrd/Proc2FRawAB/ReadFits: NZones=" << NZones << " NbPaq=" << NPaqinZone 
+         << " NPaq in file=" << npaqf
+         << " PaqSz=" << paqsz << " NMaxZ=" << nmaxz << " NMean=" << NMean << endl;
+  }
+  else {
+    paqsz = GPaqSz;
+    nmaxz = NGenZ;
+    cout << " mcrd/Proc2FRawAB/GeneratePaquets: NZones=" << NZones << " NbPaq=" << NPaqinZone 
+         << "  PaqSz=" << paqsz << " NMean=" << NMean << endl;
+  }
+  RAcqMemZoneMgr mmgr1(NZones, NPaqinZone, paqsz, sizeof(complex<r_4>)*paqsz);
+  mmgr1.SetFinalizedMask((uint_4)(MemZS_ProcA)|(uint_4)(MemZS_ProcB));
+//  mmgr1.SetFinalizedMask((uint_4)(MemZS_ProcA));
+  RAcqMemZoneMgr mmgr2(NZones, NPaqinZone, paqsz, sizeof(complex<r_4>)*paqsz);
+  mmgr2.SetFinalizedMask((uint_4)(MemZS_ProcA)|(uint_4)(MemZS_ProcB));
+//  mmgr2.SetFinalizedMask((uint_4)(MemZS_ProcA));
+
+  BRFitsReader reader1(mmgr1, infiles1, fgnotrl);
+  BRFitsReader reader2(mmgr1, infiles2, fgnotrl);
+
+  TestPCIWrapperNODMA pciw1(paqsz,LossRate);
+  PCIEReader pcird1(pciw1, paqsz, paqsz, mmgr1, nmaxz, BR_Copy);
+  TestPCIWrapperNODMA pciw2(paqsz,LossRate);
+  PCIEReader pcird2(pciw2, paqsz, paqsz, mmgr2, nmaxz, BR_Copy);
+
+  string outname1 = outname;
+  outname1 += "/Ch12";
+  BRProcARaw2C proc1(mmgr1, outname1, NMean, nmaxz, fgnotrl);
+  string outname2 = outname;
+  outname2 += "/Ch34";
+  BRProcARaw2C proc2(mmgr2, outname2, NMean, nmaxz, fgnotrl,2);
+  string outname12 = outname;
+  outname12 += "/Ch1234";
+  BRProcBRaw4C proc12(mmgr1, mmgr2, outname12, NMean, nmaxz, fgnotrl);
+
+  cout << " mcrd/Proc2FRawAB: Starting threads (reader1,2, procA1,2, procAB) ... " << endl;
+
+  if (fgrdfile) { 
+    reader1.start();
+    reader2.start();
+  }
+  else { 
+    pcird1.start();
+    pcird2.start();
+  }
+  proc1.start();
+  proc2.start();
+  proc12.start();
+
+  sleep(1);
+  cout << " mcrd/Proc2FRawAB: Waiting for reader threads to finish ... " << endl;
+  if (fgrdfile) { 
+    reader1.join();
+    reader2.join();
+  }
+  else { 
+    pcird1.join();
+    pcird2.join();
+  }
+  cout << " mcrd/Proc2FRawAB: Readers finished, waiting for process thread to finish ... " << endl;
+  sleep(2);
+  mmgr1.Stop();
+  mmgr2.Stop();
+  proc1.join();
+  proc2.join();
+  proc12.join();
+  mmgr1.Print(cout);
+  mmgr2.Print(cout);
+  return 0;
+}
+
+
+/* --Fonction-- */
+int Usage(bool fgshort)
+{
+  cout << " --- mcrd.cc : Reading/Processing BAORadio FITS files" << endl;
+  cout << " Usage:  mcrd ACT OutPath InPath [InPath2] Imin,Imax\n" 
+       << "              [NZones,NPaqinZone] [NMean] [GPaqSz,NGenZones,LossRate]" << endl;
+  if (fgshort) {
+    cout << " mcrd -h for detailed instructions" << endl;
+    return 1;
+  }
+  cout << " ACT= -2 , -2g , -2nt -> 1 fiber, 2 raw channel processing (ProcA)\n"
+       << " ACT= -4 , -4g , -4g , -4nt -> 2 fibers, 4 raw channels (ProcA, ProcB)\n"
+       << "   nt (notrl) -> FITS files without frame trailer \n" 
+       << "   g (generate paquets) -> generate paquets instead of reading fits files" <<endl; 
+  cout << " OutPath : Output directory name " << endl;
+  cout << " InPath [InPath2] Imin,Imax: Input fits files directory name(s)\n"
+       << "    (Inpath=Fiber1, InPath2=Fiber2) and sequence numbers \n" 
+       << "    FileNames=InPath/signalII.fits Imin<=II<=Imax \n"
+       << " NZones,NbPaqinZone : Number of Zones and number of paquets in one zone\n"
+       << "     of the RAcqMemZoneMgr memory manager (default = 4,128)\n"
+       << " NMean: Number of packet used for spectra/visibility computation (def=1024)\n"
+       << " GPaqSz,NGenZones,LossRate: Paquet Size, Number of memory zones filled and\n"
+       << "      loss rate (-2g,-4g) , default=16424,100,0.1" << endl;
+  return 1;
+}
Index: /trunk/AddOn/TAcq/pciewrap.cc
===================================================================
--- /trunk/AddOn/TAcq/pciewrap.cc	(revision 3644)
+++ /trunk/AddOn/TAcq/pciewrap.cc	(revision 3645)
@@ -11,5 +11,5 @@
 
 /* --Methode-- */
-TestPCIWrapperNODMA::TestPCIWrapperNODMA(UInt32 sz) 
+TestPCIWrapperNODMA::TestPCIWrapperNODMA(UInt32 sz, double lossrate) 
   : PCIEWrapperInterface() , size_(sz)
 {
@@ -20,5 +20,7 @@
   frame_counter_ = 0;
   timetag_ = 0;
-  tottransfer_ = 0;	
+  tottransfer_ = 0;
+  lossrate_ = lossrate;
+  cout << " TestPCIWrapperNODMA(PaqSz=" << sz << ",LossRate=" << lossrate << ")" << endl;
 }
 
@@ -45,5 +47,10 @@
 Byte* TestPCIWrapperNODMA::GetData()
 {
-  frame_counter_ ++;
+  if (lossrate_ > 1.e-19) {
+    UInt32 dfc = 1; 
+    while (rg_.Flat01()<lossrate_)  dfc++;
+    frame_counter_ += dfc;
+  }
+  else frame_counter_ ++;
   timetag_ = frame_counter_ * size_ / 2;
   BRPaquet paq(data_, size_);
Index: /trunk/AddOn/TAcq/pciewrap.h
===================================================================
--- /trunk/AddOn/TAcq/pciewrap.h	(revision 3644)
+++ /trunk/AddOn/TAcq/pciewrap.h	(revision 3645)
@@ -6,4 +6,5 @@
 #include "brpaqu.h"
 #include <string>
+#include "randr48.h"  // Generateur aleatoire SOPHYA pour simulation perte de paquets
 
 /* 
@@ -45,5 +46,5 @@
 class TestPCIWrapperNODMA : public PCIEWrapperInterface {
 public:	
-  TestPCIWrapperNODMA(UInt32 sz);
+  TestPCIWrapperNODMA(UInt32 sz, double lossrate=0.);
   virtual ~TestPCIWrapperNODMA();
 
@@ -60,5 +61,8 @@
   UInt64 timetag_; 	
   UInt64 tottransfer_;
+  double lossrate_;
   BRPaqChecker pchk_;
+//  FMTRandGen rg_;
+  ThSDR48RandGen rg_;
 };
 
Index: /trunk/AddOn/TAcq/tmtacq.cc
===================================================================
--- /trunk/AddOn/TAcq/tmtacq.cc	(revision 3644)
+++ /trunk/AddOn/TAcq/tmtacq.cc	(revision 3645)
@@ -410,9 +410,11 @@
   else {
     dmap = new DMAMgr(card,patternSZ,dmaSize,activate_pattern); 
-    if (! dmap->StatusFibre() ) {
-      cout << " tmtacq[3] - fibre non accrochee -> exit " << endl;
-      throw PCIEWException(" Fibre non accrochee ");
+    if (!activate_pattern) {
+      if (! dmap->StatusFibre() ) {
+        cout << " tmtacq[3] - fibre non accrochee -> exit " << endl;
+        throw PCIEWException(" Fibre non accrochee ");
+      }
+      else cout << " tmtacq[3] - fibre accrochee OK " << endl;
     }
-    else cout << " tmtacq[3] - fibre accrochee OK " << endl;
     pciwp = new PCIEWrapper(*dmap); 
   }
@@ -509,16 +511,18 @@
   else {
     dmap1 = new DMAMgr(cardlist[0],patternSZ,dmaSize,activate_pattern); 
-    if (! dmap1->StatusFibre() ) {
-      cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[0] << " -> exit " << endl;
-      throw PCIEWException(" Fibre non accrochee 1");
+    if (!activate_pattern) {
+      if (! dmap1->StatusFibre() ) {
+        cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[0] << " -> exit " << endl;
+        throw PCIEWException(" Fibre non accrochee 1");
+      }
+      else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[0] << endl;
+
+      dmap2 = new DMAMgr(cardlist[1],patternSZ,dmaSize,activate_pattern); 
+      if (! dmap2->StatusFibre() ) {
+        cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[1] << " -> exit " << endl;
+        throw PCIEWException(" Fibre non accrochee 2");
+      }
+      else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[1] << endl;
     }
-    else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[0] << endl;
-
-    dmap2 = new DMAMgr(cardlist[1],patternSZ,dmaSize,activate_pattern); 
-    if (! dmap2->StatusFibre() ) {
-      cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[1] << " -> exit " << endl;
-      throw PCIEWException(" Fibre non accrochee 2");
-    }
-    else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[1] << endl;
     pciwp1 = new PCIEWrapper(*dmap1); 
     pciwp2 = new PCIEWrapper(*dmap2); 
