Index: trunk/Poubelle/archTOI.old/archeopsfile.cc
===================================================================
--- trunk/Poubelle/archTOI.old/archeopsfile.cc	(revision 315)
+++ trunk/Poubelle/archTOI.old/archeopsfile.cc	(revision 342)
@@ -38,4 +38,5 @@
   
   SSTHandler sstHandler;
+  GPSParser  gpsParser;
 };
 
@@ -211,4 +212,6 @@
       else if (!llastBolo) {
         llastBolo = new block_type_bolo;
+      }
+      if (llastBolo) {
         memcpy(llastBolo, lastBolo, sizeof(block_type_bolo));
       }
@@ -286,4 +289,8 @@
   fn         = x.fn;
   f = fopen(fn.c_str(), "rb");
+
+  rawMJD     = x.rawMJD;
+  startMJD   = x.startMJD;
+  utcOffset  = x.utcOffset;
 }
 
@@ -300,5 +307,5 @@
   //curBlock = oldFile.curBlock;
   //peekBlock = oldFile.peekBlock;
-  peekPos = 0;
+  if (peekPos>0) peekPos = 0;
   setUTCOffset(oldFile.utcOffset);
 }
@@ -306,4 +313,6 @@
 
 def_nom_block
+
+def_long_block
 
 bool ArcheopsFile::nextBlock() {
@@ -316,23 +325,46 @@
   
   memcpy(curBlock, peekBlock, sizeof(block_type_modele));
-  
-  if (peekPos+12 > fLen) return false;
-  fseek(f,peekPos,SEEK_SET);
-  size_t read = fread(peekBlock,1,sizeof(block_type_modele),f);
-  swapEntete(peekBlock);
-  if (read < longueur_block(peekBlock)) return false;
-  swapContent(peekBlock);
-  if (verifie_block(peekBlock) != block_correct) {
-  printf("block invalide\n"); throw ArchExc("invalid block");
-  }
-  peekPos += longueur_block(peekBlock);
+  curPos = peekPos;
+  
+  while (true) {
+    if (peekPos+12 > fLen) return false;  // fin de fichier
+    fseek(f,peekPos,SEEK_SET);            // aller en peekPos
+    size_t read = fread(peekBlock,1,sizeof(block_type_modele),f);
+    swapEntete(peekBlock);
+    if (read < longueur_block(peekBlock) || 
+        type_block(peekBlock) < 0 || type_block(peekBlock) > 19 ||
+        longueur_block(peekBlock) != long_block[type_block(peekBlock)]) {
+      cout << "block de type/longueur invalide" << endl;
+      memset(peekBlock, 0, sizeof(block_type_modele)); // don't keep trash...
+      peekPos = searchNextBlock(peekPos);
+      if (peekPos<0) return false;
+      continue;
+    }
+    swapContent(peekBlock);
+    if (verifie_block(peekBlock) != block_correct) {
+      cout << "block invalide " << numero_block(peekBlock);
+      if (!fixBlock(peekBlock)) {
+        cout << " -- skipped" << endl;
+        peekPos += longueur_block(peekBlock);  // la longueur doit etre ok...
+        continue;
+      } else {
+        cout << " -- fixed" << endl;
+        break;
+      }
+    }
+    break; // tout semble bon pour ce bloc...
+  }
+  
+  peekPos += longueur_block(peekBlock); // on suppose que longueur OK...
   if (curPos < 0) {
     curPos = 0; return true;
   }
-  curPos += longueur_block(curBlock);
-  curRawKind = curKind = type_block(curBlock);
-  //printf("block %d  :  %s \n",numero_block(&curBlock),nom_block[curKind]);
-  postProcessBlock();
-  saveCurBlock();
+  if (curBlock->debut != 0) {
+    curRawKind = curKind = type_block(curBlock);
+    postProcessBlock();
+    saveCurBlock();
+  } else {
+    curRawKind = curKind = -1;
+  }
   return true;
 }
@@ -346,4 +378,9 @@
 }
 
+bool ArcheopsFile::fixBlock(block_type_modele* blk) {
+  return false;
+}
+
+
 int  ArcheopsFile::blockKind() {
   return curKind;
@@ -363,4 +400,5 @@
   double p,f1,f2,f3;
   int pp;
+  if (!lastReglage()) return -1;
   pp=lastReglage()->reglage.horloge.periode;
   p=pp/5.;
@@ -374,5 +412,5 @@
 
 int ArcheopsFile::nEchBlock() {  // Nb d'echantillons dans un bloc
-  return lastParam()->param.n_per_block*2.;
+  return lastParam()->param.n_per_block*2;
 }
 
@@ -448,4 +486,10 @@
 }
 
+void ArcheopsFile::forceBlock(block_type_modele* blk) {
+  blockSet->setBloc(*blk);
+}
+
+#define place_paquet(i,j)	 ((i/8) * 24  + j*8 + (i%8) )
+
 void ArcheopsFile::postProcessBlock() {
   switch (curKind) {
@@ -454,8 +498,24 @@
        block_type_bolo blk2;
        block_type_bolo_comprime* blk = (block_type_bolo_comprime*) &blockSet->curBlock;
+       #if version_num <= 25
        for(int j=0;j<nb_bolo_util;j++)	
-		{
-		   decompress_7_2(blk->data_bolo[j],blk2.data_bolo[j],nb_per_block*2);
+	   {
+		   decompress_7_2((int4*)blk->data_bolo[j],blk2.data_bolo[j],nb_per_block*2);
+	   }
+	   #else
+	   block_type_param* param = lastParam();
+	   int jc=0;for(int j=0;j<nb_max_bolo;j++)	 // jc = bolo_comprime  //   j=bolo normal
+	   {
+		if( (param->param.bolo[j].bolo_code_util==bolo_normal_transmis) &&  (jc<nb_bolo_util)  )
+			{
+			decompress_7_2((int4 *)blk->data_bolo[jc],blk2.data_bolo[j],nb_per_block*2);
+			jc++;
+			}
+		else {
+		  memset(blk2.data_bolo[j], 0, nb_per_block*2*sizeof(int4));
 		}
+		}
+
+	   #endif
        valide_block((block_type_modele*)&blk2,block_bolo,numero_block(blk));	
        memcpy(&blockSet->curBlock,&blk2,sizeof(blk2));
@@ -464,7 +524,43 @@
      }
      case block_sst_comprime: {  // $CHECK$ TBD
+       blockSet->setRawBloc(blockSet->curBlock);
+       block_type_sst blk2;
+       block_type_sst_comprime* blk = (block_type_sst_comprime*) &blockSet->curBlock;
+       for (int j=0; j<18; j++)
+         for (int i=0; i<nb_per_block*2; i++)
+           blk2.sst[i][j] = 0;
+
+       int jc=0;
+       for( int j=0;j<48;j++) {
+         if ((j!=0) && (j!=4)) 
+         {
+           unsigned int4 sst_vrai[nb_per_block*2];
+           decompress_4_1((int4*)blk->sst[jc],(int4*)sst_vrai,nb_per_block*2);
+           for (int k=0;k<nb_per_block*2;k++) {
+             unsigned int4 a,b0,b1,b2;
+             b2 = sst_vrai[k] & 0xf;
+             b1 = (sst_vrai[k] >> 4) & 0xf;
+             b0 = (sst_vrai[k] >> 8) & 0xf;
+	         a=place_paquet(j,0);
+	         blk2.sst[k][a/8] |= (b0 << (a%8)*4);
+	         a=place_paquet(j,1);
+	         blk2.sst[k][a/8] |= (b1 << (a%8)*4);
+	         a=place_paquet(j,2);
+	         blk2.sst[k][a/8] |= (b2 << (a%8)*4);
+           }
+           jc++;
+         }
+       }       
+       valide_block((block_type_modele*)&blk2,block_sst,numero_block(blk));	
+       memcpy(&blockSet->curBlock,&blk2,sizeof(blk2));
+       curKind = block_sst;
+       blockSet->sstHandler.ProcessBlock((block_type_sst*)&blockSet->curBlock);
+       break;
      }
      case block_sst : {
        blockSet->sstHandler.ProcessBlock((block_type_sst*)&blockSet->curBlock);
+     }
+     case block_gps : {
+       blockSet->gpsParser.ProcessBlock((block_type_gps*)&blockSet->curBlock);
      }
   }
@@ -519,16 +615,20 @@
 #endif
 
+#ifdef SWAP
 void ArcheopsFile::swapEntete(block_type_modele* blk) {
-#ifdef SWAP
   bswap4(&(blk->debut));
   bswap4(&(blk->code1));
   bswap4(&(blk->code2));
   long lg = longueur_block(blk);
-  bswap4(((char*)blk) + lg - 4);
+  if (lg < taille_maxi_block_archeops)
+    bswap4(((char*)blk) + lg - 4);
+}
+#else
+void ArcheopsFile::swapEntete(block_type_modele* ) {
+}
 #endif
-}
-
+
+#ifdef SWAP
 void ArcheopsFile::swapContent(block_type_modele* blk) {
-#ifdef SWAP
   int typ = type_block(blk);
 
@@ -550,11 +650,41 @@
     for (int i=0; i<nb_max_bolo; i++)
       for (int j=0; j<8; j++)
-	bswap4(&b->param.bolo[i].bolo_nom[4*j]);
-  }
-  
-  }
+#if version_num<=25
+        bswap4(&b->param.bolo[i].bolo_nom[4*j]);
+#else
+	bswap4(&b->param.nom_coef[i].bolo_nom[4*j]);
 #endif
-}
-  
+  }
+  
+  }
+}
+#else
+void ArcheopsFile::swapContent(block_type_modele* ) {
+}
+#endif
+  
+long ArcheopsFile::searchNextBlock(long pos) {
+  static char* buffer = 0;
+  static int4  debswp = debut_block_mesure;
+  static int4  longmax = taille_maxi_block_archeops*20;
+  if (!buffer) {
+    buffer = new char[longmax];
+#ifdef SWAP
+    bswap4(&debswp);
+#endif
+  }
+  fseek(f,pos,SEEK_SET);
+  size_t read = fread(buffer,1,taille_maxi_block_archeops*2,f);
+  //if (read<taille_maxi_block_archeops*2) return -1;
+  for (int i=4; i<read; i+=4) {
+    if (*(int4*)(buffer+i) == debswp) {
+      cout << "trying to skip " << i << " bytes to pos="<<pos+i << endl;
+      return pos+i;
+    }
+  }
+  cout << "cannot find block start" << endl;
+  return -1;
+}
+
   
 
@@ -562,7 +692,37 @@
 static int mlen[] = {31,28,31,30,31,30,31,31,30,31,30,31};
 
+double ArcheopsFile::decodeMJD(string const& dateString) {
+  //99_04_29-15h36m22  ou  99_05_10
+  short y,m,d,hh,mm,ss;
+  char const* p = dateString.c_str();
+  char const* p2 = dateString.c_str() + dateString.length();
+  y  = atoi(p); p+=3; if (p>p2) return -1;
+  m  = atoi(p); p+=3; if (p>p2) return -1;
+  d  = atoi(p); p+=3;
+  if (p<p2) {
+  hh = atoi(p); p+=3; if (p>p2) return -1;
+  mm = atoi(p); p+=3; if (p>p2) return -1;
+  ss = atoi(p);
+  } else {
+    hh=mm=ss=0;
+  }
+
+  if (y<50) y += 100;
+  // 1. depuis 0/1/97 minuit
+  double mjd = (int) (365.25 * (y-97));
+  for (int i=0; i<m-1; i++)
+    mjd += mlen[i];
+  if (y%4 == 0 && m > 2) mjd++;
+  mjd += d;
+  mjd += hh/24. + mm/24./60. + ss/24./60./60;
+  
+  mjd += 448.5; // 0/1/97 minuit
+
+  return mjd;
+}
+
 void ArcheopsFile::computeMJD(string const& fname) {
-  //h99_04_29-15h36m22
-  short y,m,d,hh,mm,ss;
+  //telemetrie : h99_04_29-15h36m22
+  //enregistreur : ARKxxxxxx.dat, et MJD = samedi 17 juillet, 21h -> 1377.4
   char const* p = fname.c_str();
   char const* p2 = p  + fname.length()-1;
@@ -570,21 +730,9 @@
   if (*p2 == ':' || *p2 == '/') p2++;
   if (*p2 == 'h') p2++;
-  y  = atoi(p2); p2+=3;
-  m  = atoi(p2); p2+=3;
-  d  = atoi(p2); p2+=3;
-  hh = atoi(p2); p2+=3;
-  mm = atoi(p2); p2+=3;
-  ss = atoi(p2);
-  
-  if (y<50) y += 100;
-  // 1. depuis 0/1/97 minuit
-  rawMJD = (int) (365.25 * (y-97));
-  for (int i=0; i<m-1; i++)
-    rawMJD += mlen[i];
-  if (y%4 == 0 && m > 2) rawMJD++;
-  rawMJD += d;
-  rawMJD += hh/24. + mm/24./60. + ss/24./60./60;
-  
-  rawMJD += 448.5; // 0/1/97 minuit
+  if (!strncmp(p2, "ARK",3)) {
+    rawMJD = 1377.4;
+  } else {
+    rawMJD = decodeMJD(p2);
+  }
   startMJD = rawMJD - utcOffset/24.;
 }
@@ -610,4 +758,10 @@
 
 
+int ArcheopsFile::getGyroBlockNum() {
+  if (!lastGyro()) return -1;
+  return numero_block(lastGyro());
+}
+
+
 // GPS
 // $GPGGA,hhmmss.ss,ddmm.mmmm,n,dddmm.mmmm,e,q,ss,y.y,a.a,z,
@@ -621,16 +775,19 @@
 double ArcheopsFile::getGPSUTC() {  // en secondes depuis minuit UTC jour courant
   if (!lastGPS()) return -9.e99;
-  char* p = lastGPS()->gps;
-  if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
-  p += 7;
+  return blockSet->gpsParser.getUTC();
+/*  char* p = lastGPS()->gps;
+  //if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  //p += 7;
+  if (*p != '$') return -9.e99;
+  p += 1;
   double t;
   sscanf(p, "%lg", &t);
   int h = int(t/10000); t -= h*10000;
   int m = int(t/100);   t -= m*100;
-  return h*3600. + m*60. + t;
+  return h*3600. + m*60. + t;*/
 }
 
 double ArcheopsFile::getGPSMJD() {  // modified julian day du dernier bloc GPS, JD - 2450000
-  double t = getGPSUTC()/86400.;
+  double t = getGPSUTC()/86400. - 0.5;
   if (t<0) return t;
   if (t > (startMJD - int(startMJD))) {
@@ -643,8 +800,10 @@
 double ArcheopsFile::getGPSLat() {  // degres, +  = NORD
   if (!lastGPS()) return -9.e99;
-  char* p = lastGPS()->gps;
-  if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  return blockSet->gpsParser.getLatitude();
+  /*char* p = lastGPS()->gps;
+  //if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  if (*p!='$') return -9.e99;
   char* fence = p+80;
-  p += 7;
+  p += 1;
   while (*p != ',' && p<fence) p++;
   if (*p != ',') return -9.e99; 
@@ -658,13 +817,16 @@
   p++;
   if (*p == 'S') t = -t;
-  return t;
-}
+  return t;*/
+}
+
 
 double ArcheopsFile::getGPSLong() { // degres, +  = EST
   if (!lastGPS()) return -9.e99;
-  char* p = lastGPS()->gps;
-  if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  return blockSet->gpsParser.getLongitude();
+  /*char* p = lastGPS()->gps;
+  //if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  if (*p!='$') return -9.e99;
   char* fence = p+80;
-  p += 7;
+  p += 1;
   for (int i=0; i<3; i++) {
     while (*p != ',' && p<fence) p++;
@@ -680,14 +842,49 @@
   p++;
   if (*p == 'W') t = -t;
-  return t;
-}
-
+  return t;*/
+}
+
+double ArcheopsFile::getGPSAlt() { // meters from sea level
+  if (!lastGPS()) return -9.e99;
+  return blockSet->gpsParser.getAltitude();
+  /*char* p = lastGPS()->gps;
+  //if (strncmp(p, "$GPGGA,", 7)) return -9.e99;
+  if (*p!='$') return -9.e99;
+  char* fence = p+80;
+  p += 1;
+  for (int i=0; i<8; i++) {
+    while (*p != ',' && p<fence) p++;
+    if (*p != ',') return -9.e99; 
+    p++;
+  }
+  double t;
+  sscanf(p, "%lg", &t);
+  return t;*/
+}
+
+bool ArcheopsFile::hasGPSTime() { 
+  if (!lastGPS()) return false;
+  return blockSet->gpsParser.hasGPSTime();
+}
+
+bool ArcheopsFile::hasGPSPos() { 
+  if (!lastGPS()) return false;
+  return blockSet->gpsParser.hasPosition();
+}
+
+bool ArcheopsFile::hasGPSAlt() { 
+  if (!lastGPS()) return false;
+  return blockSet->gpsParser.hasAltitude();
+}
 
 
 // Bolo
+#define  val_DS(j,i)  (blk->data_bolo[j][i]&0x1fffff)
+
 
 long ArcheopsFile::getRawBolo(int ibolo, int imesure) {    // donnee brute, avec seulement soustraction offset
   int nb_coups,aa;  
   block_type_bolo* blk = imesure >= 0 ? lastBolo() : llastBolo();
+  //cout << "raw " << imesure << " ";
   if (imesure < 0) imesure += nEchBlock();
   if (!blk) return 0;
@@ -699,6 +896,8 @@
   
   int s = imesure % 2 ? 1 : -1;
-
-  return s*(((blk->data_bolo[ibolo][imesure]-aa)<<1)/nb_coups);
+  
+  //cout << s*(((val_DS(ibolo,imesure)-aa)<<1)/nb_coups) << "\n";
+
+  return s*(((val_DS(ibolo,imesure)-aa)<<1)/nb_coups);
 }
 
@@ -706,8 +905,11 @@
 
 double ArcheopsFile::getMuVBolo(int ibolo, int imesure) { // microvolts, filtre avec filtre carre
-  double y = (getRawBolo(ibolo, imesure-1) - getRawBolo(ibolo, imesure))/2.;
-  if (imesure%2) y=-y;
+  double y = (getRawBolo(ibolo, imesure-1) + getRawBolo(ibolo, imesure))/2.;
+  //if (imesure%2) y=-y;
   block_type_reglage* reglage = lastReglage();
-  return ((1e5*y)/(65536.*gain_ampli(reglage->reglage.bolo[ibolo])));
+  block_type_param*   param = lastParam();
+  //cout << "muv " << imesure << " " << y << "\n";
+  return bol_micro_volt(y,(double)param->param.bolo[ibolo].bolo_gain*gain_ampli(reglage->reglage.bolo[ibolo]));
+  //return ((1e5*y)/(65536.*gain_ampli(reglage->reglage.bolo[ibolo])));
 }
 
@@ -719,8 +921,34 @@
 }
 
-
 long ArcheopsFile::getSSTSignal(int idiode, int imesure) {
   return blockSet->sstHandler.getSignal(imesure, idiode);
 }
+
+long ArcheopsFile::getSSTRawSignal(int idiode, int imesure) {
+  return blockSet->sstHandler.getRawSignal(imesure, idiode);
+}
+
+double ArcheopsFile::getSSTStarZ(int istar, int imesure) {
+  return blockSet->sstHandler.getStarZ(imesure, istar);
+}
+
+double ArcheopsFile::getSSTStarF(int istar, int imesure) {
+  return blockSet->sstHandler.getStarF(imesure, istar);
+}
+
+long ArcheopsFile::getGyro(int igyro, int imesure) {   
+  if (igyro<0 || igyro>2) return 0;
+  if (imesure<0 || imesure>= nb_per_block*2) return 0;
+  block_type_gyro* blk = lastGyro() ;
+  if (!blk) return 0;
+#if version_num<=25
+  return blk->gyros[igyro][imesure];
+#else
+  return blk->gyro[igyro][imesure];
+#endif
+}
+
+
+
 // $CHECK$ TBD
 
