Index: trunk/SophyaExt/FitsIOServer/fabtcolread.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2453)
+++ trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2456)
@@ -43,5 +43,6 @@
 {
   FitsFN = "";
-  NHdu = -1;
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
   FitsPtr = NULL;
 }
@@ -52,5 +53,5 @@
 FitsOpenFile::FitsOpenFile(FitsOpenFile& fof)
 {
-  Init(fof.GetFileName().c_str());
+  Init(fof.FileName().c_str());
 }
 
@@ -62,5 +63,6 @@
   Delete();
   FitsFN = "";
-  NHdu = 0;
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
 }
 
@@ -80,33 +82,100 @@
 void FitsOpenFile::Init(const char* fname)
 {
-   // Parametres Generaux
-   FitsFN = fname;
-   NHdu = 0;
-   FitsPtr = NULL;
-
-   // Ouverture du fichier
-   if(FitsFN.size() <= 0 )
-      throw ParmError("FitsOpenFile::Init: Fits file name error\n");
-
-   int sta = 0;
-   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READONLY,&sta)) {
-     printerror(sta);
-     FitsPtr = NULL;
-     throw NullPtrError("FitsOpenFile::Init: Error opening Fits file\n");
-   }
-
-   // Get number of hdu
-   if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
-     printerror(sta);
-     NHdu = 0;
-     Delete();
-     throw NotAvailableOperation("FitsOpenFile::Init: Error getting NHdu\n");
-   }
-   if(NHdu<=0) {
-     Delete();
-     throw SzMismatchError("FitsOpenFile::Init: Bad NHdu\n");
-   }
-
- }
+  // Parametres Generaux
+  FitsFN = fname;
+  NHdu = IHdu = HduType = 0;
+  HasBeenPos = false;
+  FitsPtr = NULL;
+
+  // Ouverture du fichier
+  if(FitsFN.size() <= 0 )
+     throw ParmError("FitsOpenFile::Init: Fits file name error\n");
+
+  int sta = 0;
+  if(fits_open_file(&FitsPtr,FitsFN.c_str(),READONLY,&sta)) {
+    printerror(sta);
+    FitsPtr = NULL;
+    throw NullPtrError("FitsOpenFile::Init: Error opening Fits file\n");
+  }
+
+  // Get number of hdu
+  if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
+    printerror(sta);
+    NHdu = 0;
+    Delete();
+    throw NotAvailableOperation("FitsOpenFile::Init: Error getting NHdu\n");
+  }
+  if(NHdu<=0) {
+    Delete();
+    throw SzMismatchError("FitsOpenFile::Init: Bad NHdu\n");
+  }
+
+  MoveToHDU(1);
+}
+
+/*! Move to an HDU
+\param ihdu: hdu number to move
+\warning ihdu = [1,nhdu]
+\return 0 if positionning failed, ihdu if success
+*/
+int FitsOpenFile::MoveToHDU(int ihdu)
+{
+ if(FitsPtr==NULL)
+   throw NullPtrError("FitsOpenFile::MoveToHDU: no fits file open FitsPtr==NULL\n");
+ int ihdusave = IHdu;
+ if(ihdu<=0) ihdu=1; if(ihdu>NHdu) ihdu=NHdu;
+ int sta=0;
+ if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) {
+   printerror(sta);
+   // On se repositionne ou on etait
+   fits_movabs_hdu(FitsPtr,ihdusave,&HduType,&sta);
+   IHdu = ihdusave;
+ } else IHdu = ihdu;
+ return IHdu;
+}
+
+/*! Move to the first HDU of a certain type
+\param hdutype: type of the hdu
+\param hdudeb: start at that hdu
+\return the type of HDU the file is positionned
+*/
+int FitsOpenFile::MoveToFirst(int hdutype,int ihdudeb)
+{
+ if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
+ int ihdusave = IHdu;
+ for(int ihdu=ihdudeb;ihdu<=NHdu;ihdu++) {
+   MoveToHDU(ihdu);
+   if(HduType==hdutype) break;
+ }
+ // Si echec, on se repositionne ou on etait
+ if(HduType!=hdutype) MoveToHDU(ihdusave);
+ return HduType;
+}
+
+/*! Move to the last HDU of a certain type
+\param hdutype: type of the hdu
+\param hdudeb: stop at that hdu
+\return the type of HDU the file is positionned
+*/
+int FitsOpenFile::MoveToLast(int hdutype,int ihdudeb)
+{
+ if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
+ int ihdusave = IHdu;
+ for(int ihdu=NHdu;ihdu>=ihdudeb;ihdu--) {
+   MoveToHDU(ihdu);
+   if(HduType==hdutype) break;
+ }
+ // Si echec, on se repositionne ou on etait
+ if(HduType!=hdutype) MoveToHDU(ihdusave);
+ return HduType;
+}
+
+/*! Print */
+void FitsOpenFile::Print(void)
+{
+ cout<<"FitsOpenFile::Print: "<<FitsFN
+     <<" hdu="<<IHdu<<"/"<<NHdu<<" type="<<HduType
+     <<" hasbeenpos="<<HasBeenPos<<endl;
+}
 
 //////////////////////////////////////////////////////////////
@@ -121,5 +190,5 @@
 double FitsOpenFile::ReadKey(fitsfile *fitsptr,char *keyname)
 {
- if(keyname==NULL) return 0.;
+ if(keyname==NULL || fitsptr==NULL) return 0.;
  int sta=0; double val=0.;
  if(fits_read_key(fitsptr,TDOUBLE,keyname,&val,NULL,&sta))
@@ -136,5 +205,5 @@
 long FitsOpenFile::ReadKeyL(fitsfile *fitsptr,char *keyname)
 {
- if(keyname==NULL) return 0;
+ if(keyname==NULL || fitsptr==NULL) return 0;
  int sta=0; long val=0;
  if(fits_read_key(fitsptr,TLONG,keyname,&val,NULL,&sta))
@@ -151,5 +220,5 @@
 string FitsOpenFile::ReadKeyS(fitsfile *fitsptr,char *keyname)
 {
- if(keyname==NULL) return (string)"";
+ if(keyname==NULL || fitsptr==NULL) return (string)"";
  int sta=0; char val[FLEN_VALUE];
  if(fits_read_key(fitsptr,TSTRING,keyname,val,NULL,&sta))
@@ -189,4 +258,5 @@
   // Select the column to be read
   FitsABTColRd fbt(fof,"BoloMuv_28",0,1000,1,3);
+  FitsABTColRd fbt2(fof,"BoloMuv_29",0,1000,1,3);
   fbt.SetDebug(3);
   fbt.Print(3);
@@ -194,5 +264,6 @@
   for(long i=0;i<fbt.GetNbLine();i++) {
     double x = fbt.Read(i);
-    if(i%lpmod==0) cout<<i<<": "<<x<<endl;
+    double y = fbt2.Read(i);
+    if(i%lpmod==0) cout<<i<<": "<<x<<", "<<y<<endl;
   }
   // Read into a vector
@@ -203,4 +274,6 @@
   n = fbt.Read(10,-1,data);
     cout<<"Number of values read: "<<n<<endl;
+  TVector<double> data2;
+  fbt2.Read(32,50,data);
   // Close the fits file
   delete fof;
@@ -218,5 +291,6 @@
   \param lp : debug level
   \verbatim
-  - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
+  - if ihdu<=0 first BINARY or ASCII table is taken
+  - if ihdu>nhdu ihdu is set to nhdu
   - bsens>0    read forward
     bsens<0    read backward
@@ -247,5 +321,5 @@
 {
   Init(fbt.GetFitsOpenFile(),fbt.GetColLabel().c_str()
-      ,fbt.GetColNum(),fbt.GetHDU()
+      ,fbt.GetColNum(),fbt.HDU()
       ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
 }
@@ -254,8 +328,6 @@
 FitsABTColRd::FitsABTColRd()
 {
- FitsFN = "";
  ColLabel = ""; ColTUnit = ""; ColTForm = "";
  ColNum = -1; ColTypeCode = 0;
- IHdu = 0; NHdu = 0; HduType = 0;
  NBcol = 0; NBline = 0;
  SetNulVal(); SetDebug(0);
@@ -271,94 +343,66 @@
 {
  // Initialisation des Parametres Generaux
- FitsFN = "";
- ColLabel = collabel;
- ColTUnit = "";
- ColTForm = "";
- ColNum = colnum;
- ColTypeCode = 0;
- IHdu = ihdu;
- NHdu = 0;
- HduType = 0;
- NBcol = 0;
- NBline = 0;
- SetNulVal();
- SetDebug(lp);
+ ColLabel=collabel; ColTUnit=""; ColTForm=""; ColNum=colnum; ColTypeCode=0;
+ NBcol = 0; NBline = 0;
+ SetNulVal(); SetDebug(lp);
  NFitsRead = 0;
- FitsOF = NULL;
- FitsPtr = NULL;
+ FitsOF = NULL; FitsPtr = NULL;
  LineDeb = LineFin = -1;
  Buffer = NULL;
- ChangeBuffer(blen,bsens);
 
  // Caracteristiques du FitsOpenFile
  FitsOF = fof;
- if(FitsOF==NULL) {
-   Delete();
+ if(FitsOF==NULL)
    throw NullPtrError("FitsABTColRd::Init: FitsOpenFile pointer is NULL\n");
- }
+
  FitsPtr = FitsOF->GetFitsPtr();
- if(FitsPtr==NULL) {
-   Delete();
+ if(FitsPtr==NULL)
    throw NullPtrError("FitsABTColRd::Init: FitsPtr pointer is NULL\n");
- }
- NHdu = FitsOF->GetNHdu();
- if(DbgLevel>1) cout<<"FitsABTColRd::Init  NHdu="<<NHdu<<endl;
- if(NHdu<=0) {
-   Delete();
-   throw SzMismatchError("FitsABTColRd::Init: Bad NHdu\n");
- }
- FitsFN = FitsOF->GetFileName();
- if(FitsFN.size() <= 0 ) {
-   Delete();
-   throw ParmError("FitsABTColRd::Init: Fits file name error\n");
- }
 
  int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
 
  // Get HDU for bin/ascii table
- // si IHdu <=0 || >NHdu on cherche la 1ere bin/ascii table
- // sinon on se positionne sur IHdu
- if(IHdu<=0 || IHdu>NHdu)
-   for(int ihdu=1;ihdu<=NHdu;ihdu++) {
-     if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) FitsOpenFile::printerror(sta);
-     if(DbgLevel>1) cout<<"...Init ihdu="
-                        <<ihdu<<" HduType="<<HduType<<endl;
-     if(HduType==BINARY_TBL || HduType==ASCII_TBL) {IHdu = ihdu; break;}
+ // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
+ // une classe utilisant ce fichier doit le positionner sur un HDU.
+ // Par contre, si une autre classe utilise ce meme FitsOpenFile,
+ // elle ne peut le positionner que sur ce meme HDU !
+ if(FitsOF->GetPosStatus()==false) {
+   if(ihdu==0) { // find the first BINARY then the first ASCII
+     int rc = FitsOF->MoveToFirst(BINARY_TBL);
+     if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
+   } else {
+     int rc = FitsOF->MoveToHDU(ihdu);
+     if(rc!=ihdu)
+       throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
    }
- if(IHdu<=0 || IHdu>NHdu) {
-   cout<<"NO BINARY or ASCII hdu found"<<endl;
-   IHdu = 0; Delete();
-   throw TypeMismatchExc("FitsABTColRd::Init: NO BINARY or ASCII hdu found\n");
- }
- if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
-   FitsOpenFile::printerror(sta); Delete();
-   throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
- }
- if(HduType!=BINARY_TBL && HduType!=ASCII_TBL) {
-   Delete();
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
+ }
+
+ // Check HDUType and set position status to TRUE
+ if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
    throw TypeMismatchExc("FitsABTColRd::Init: HDU not ASCII/BINARY table\n");
- }
+ if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
+ FitsOF->SetPosStatus(true);
 
  // Get number of columns
  if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
-   FitsOpenFile::printerror(sta); Delete();
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of columns\n");
  }
  if(DbgLevel>1) cout<<"...Init  NBcol="<<NBcol<<endl;
- if(NBcol<1) {
-   Delete();
+ if(NBcol<1)
    throw RangeCheckError("FitsABTColRd::Init: Bad number of colums\n");
- }
 
  // Get number of rows
  if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
-   FitsOpenFile::printerror(sta); Delete();
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of rows\n");
  }
  if(DbgLevel>1) cout<<"...Init  NBline="<<NBline<<endl;
- if(NBline<1) {
-   Delete();
+ if(NBline<1)
    throw RangeCheckError("FitsABTColRd::Init: Bad number of rows\n");
- }
 
  // Get column number
@@ -367,5 +411,5 @@
    strcpy(labelcol,ColLabel.c_str());
    if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
-     FitsOpenFile::printerror(sta); Delete();
+     FitsOpenFile::printerror(sta);
      throw NotAvailableOperation("FitsABTColRd::Init: Error getting column name\n");
    }
@@ -373,20 +417,16 @@
  }
  if(DbgLevel>1) cout<<"...Init  ColNum="<<ColNum<<endl;
- if(ColNum<0 || ColNum>=NBcol) {
-   Delete();
+ if(ColNum<0 || ColNum>=NBcol)
    throw RangeCheckError("FitsABTColRd::Init: Bad column number\n");
- }
 
  // Get column type
  if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
-   FitsOpenFile::printerror(sta); Delete();
+   FitsOpenFile::printerror(sta);
    throw ParmError("FitsABTColRd::Init: Error getting column type\n");
  }
  if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
  if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX ||  ColTypeCode==TDBLCOMPLEX
-                         || ColTypeCode<0 ) {
-   Delete();
+                         || ColTypeCode<0 )
    throw ParmError("FitsABTColRd::Init: Selected column is not Numerical\n");
- }
 
  // Get column name back, tunit, tform
@@ -394,5 +434,5 @@
  long repeat=0; double tscale=1., tzero=0.;
  int rc=0;
- if(HduType==BINARY_TBL) {
+ if(HDUType()==BINARY_TBL) {
    fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform
                      ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
@@ -402,5 +442,5 @@
  }
  if(rc) {
-   FitsOpenFile::printerror(sta); Delete();
+   FitsOpenFile::printerror(sta);
    throw RangeCheckError("FitsABTColRd::Init: Error getting the column caracteristics\n");
  }
@@ -408,4 +448,7 @@
  ColTUnit = tunit;
  ColTForm = tform;
+
+ // Set the buffer for reading
+ ChangeBuffer(blen,bsens);
 
  if(DbgLevel)
@@ -779,7 +822,6 @@
    <<" ncols="<<NBcol<<" nrows="<<NBline;
  if(lp>0) os<<" NRead="<<NFitsRead;
- os<<"\n... "<<FitsFN<<"["<<IHdu<<"/"<<NHdu<<"]"
-   <<"\n... Label["<<ColNum<<"]="<<ColLabel
-   <<" TypeCode="<<ColTypeCode
+ os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"
+   <<"\n... Label["<<ColNum<<"]="<<ColLabel<<" TypeCode="<<ColTypeCode
    <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
    <<endl;
@@ -828,5 +870,6 @@
   \param lp : debug level
   \verbatim
-  - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
+  - if ihdu<=0 first BINARY or ASCII table is taken
+  - if ihdu>nhdu ihdu is set to nhdu
   - bsens>0    read forward
     bsens<0    read backward
@@ -878,5 +921,5 @@
  FitsOpenFile* fof = new FitsOpenFile(*fbt.GetFitsOpenFile());
  Init(fof,fbt.GetColLabel().c_str()
-     ,fbt.GetColNum(),fbt.GetHDU()
+     ,fbt.GetColNum(),fbt.HDU()
      ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
 }
@@ -902,8 +945,9 @@
   Constructor.
   \param fof : Pointer to the Class for opening the FITS file
-  \param ihdu : number of the HDU where the column is.
+  \param ihdu : number of the HDU where the image is.
   \param lp : debug level
   \verbatim
-  - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
+  - if ihdu<=0 first IMAGE hdu is taken
+  - if ihdu>nhdu ihdu is set to nhdu
   \endverbatim
   \warning ihdu = [1,nhdu]
@@ -917,5 +961,5 @@
 FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
 {
- Init(fbt.GetFitsOpenFile(),fbt.GetHDU(),fbt.DbgLevel);
+ Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
 }
 
@@ -923,6 +967,4 @@
 FitsImg2DRd::FitsImg2DRd()
 {
- FitsFN = "";
- IHdu = 0; NHdu = 0; HduType = 0;
  Naxis[0] = Naxis[1] = 0;
  SetNulVal(); SetDebug(0);
@@ -934,6 +976,4 @@
 {
  // Initialisation des Parametres Generaux
- FitsFN = "";
- IHdu = ihdu; NHdu = 0; HduType = 0;
  Naxis[0] = Naxis[1] = 0;
  SetNulVal(); SetDebug(lp);
@@ -944,38 +984,31 @@
  if(FitsOF==NULL)
    throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
+
  FitsPtr = FitsOF->GetFitsPtr();
  if(FitsPtr==NULL)
    throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
- NHdu = FitsOF->GetNHdu();
- if(DbgLevel>1) cout<<"FitsImg2DRd::Init  NHdu="<<NHdu<<endl;
- if(NHdu<=0)
-   throw SzMismatchError("FitsImg2DRd::Init: Bad NHdu\n");
- FitsFN = FitsOF->GetFileName();
- if(FitsFN.size() <= 0 )
-   throw ParmError("FitsImg2DRd::Init: Fits file name error\n");
 
  int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU(); 
 
  // Get HDU 2D image
- // si IHdu <=0 || >NHdu on cherche la 1ere image
- // sinon on se positionne sur IHdu
- if(IHdu<=0 || IHdu>NHdu)
-   for(int ihdu=1;ihdu<=NHdu;ihdu++) {
-     if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) FitsOpenFile::printerror(sta);
-     if(DbgLevel>1)
-       cout<<"...Init ihdu="<<ihdu<<" HduType="<<HduType<<endl;
-     if(HduType==IMAGE_HDU) {IHdu = ihdu; break;}
+ // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
+ if(FitsOF->GetPosStatus()==false) {
+   if(ihdu==0) { // find the first IMAGE_HDU
+     FitsOF->MoveToFirst(IMAGE_HDU);
+   } else {
+     int rc = FitsOF->MoveToHDU(ihdu);
+     if(rc!=ihdu)
+       throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
    }
- if(IHdu<=0 || IHdu>NHdu) {
-   cout<<"NO IMAGE_HDU hdu found"<<endl;
-   IHdu = 0;
-   throw TypeMismatchExc("FitsImg2DRd::Init: NO IMAGE_HDU hdu found\n");
- }
- if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
-   FitsOpenFile::printerror(sta);
-   throw RangeCheckError("FitsImg2DRd::Init: Error moving to requested HDU\n");
- }
- if(HduType!=IMAGE_HDU)
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
+ }
+
+ // Check HDUType and set position status to TRUE
+ if(HDUType()!=IMAGE_HDU)
    throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
+ FitsOF->SetPosStatus(true);
 
  // Get NAXIS 1 et 2
@@ -986,5 +1019,6 @@
  }
  if(DbgLevel>1)
-   cout<<"...Init(hdu="<<IHdu<<")  NAXIS1="<<Naxis[0]<<" NAXIS2="<<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
+   cout<<"...Init(hdu="<<HDU()<<")  NAXIS1="<<Naxis[0]<<" NAXIS2="
+       <<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
  if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
    throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
