Index: trunk/SophyaExt/FitsIOServer/fabtcolread.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 3572)
+++ trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 3660)
@@ -431,5 +431,5 @@
    if(fits_get_colnum(GetFitsPtr(),CASESEN,labelcol,&ColNum,&sta)) {
      FitsOpenFile::printerror(sta);
-     throw NotAvailableOperation("FitsABTColRd::Init: Error getting column name\n");
+     throw NotAvailableOperation("FitsABTColRd::Init: Error getting column number\n");
    }
    ColNum--;  // Convention [0,ncol[
@@ -974,4 +974,348 @@
 ///////////////////////////////////////////////////////////////////
 
+FitsABTColRd1F::FitsABTColRd1F(FitsOpenFile* fof,int ihdu,long blen,long bsens,int lp)
+{
+  Init(fof,ihdu,blen,bsens,lp);
+}
+
+/*! Init routine called by the constructor */
+void FitsABTColRd1F::Init(FitsOpenFile* fof,int ihdu,long blen,long bsens,int lp)
+{
+ // Initialisation des Parametres Generaux
+ ColLabel.resize(0); ColTUnit.resize(0); ColTForm.resize(0); ColTypeCode.resize(0);
+ NBcol = 0; NBline = 0;
+ SetNulVal(); SetDebug(lp);
+ FitsOF = NULL;
+ LineDeb.resize(0); LineFin.resize(0);
+ Buffer = NULL;
+
+ // Caracteristiques du FitsOpenFile
+ FitsOF = fof;
+ if(FitsOF==NULL)
+   throw NullPtrError("FitsABTColRd1F::Init: FitsOpenFile pointer is NULL\n");
+
+ if(GetFitsPtr()==NULL)
+   throw NullPtrError("FitsABTColRd1F::Init: FitsPtr pointer is NULL\n");
+
+ int sta = 0;
+ if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
+
+ // Get HDU for bin/ascii table
+ // 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("FitsABTColRd1F::Init: Error moving to requested HDU\n");
+   }
+ } else { // Fits file has already been positionned
+   if(ihdu>0 && ihdu!=HDU())
+     throw RangeCheckError("FitsABTColRd1F::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("FitsABTColRd1F::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(GetFitsPtr(),&NBcol,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of columns\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBcol="<<NBcol<<endl;
+ if(NBcol<1)
+   throw RangeCheckError("FitsABTColRd1F::Init: Bad number of colums\n");
+
+ // Get number of rows
+ if(fits_get_num_rowsll(GetFitsPtr(),&NBline,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of rows\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBline="<<NBline<<endl;
+ if(NBline<1)
+   throw RangeCheckError("FitsABTColRd1F::Init: Bad number of rows\n");
+
+ // --- Boucle sur les colonnes
+ for(int ColNum=0;ColNum<NBcol;ColNum++) {   // ***** ColNum
+   // Get column type
+   ColTypeCode.push_back(-999);
+   if(fits_get_coltypell(GetFitsPtr(),ColNum+1,&ColTypeCode[ColNum],NULL,NULL,&sta)) {
+     FitsOpenFile::printerror(sta);
+     throw ParmError("FitsABTColRd1F::Init: Error getting column type\n");
+   }
+   if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode[ColNum]<<endl;
+   if(ColTypeCode[ColNum]==TSTRING || ColTypeCode[ColNum]==TCOMPLEX
+      ||  ColTypeCode[ColNum]==TDBLCOMPLEX || ColTypeCode[ColNum]<0 )
+     throw ParmError("FitsABTColRd1F::Init: Selected column is not Numerical\n");
+   // Get column name, tunit, tform
+   char labelcol[128];
+   char tunit[64], tform[64], tdisp[64];
+   LONGLONG repeat=0; double tscale=1., tzero=0.;
+   int rc=0;
+   if(HDUType()==BINARY_TBL) {
+     fits_get_bcolparmsll(GetFitsPtr(),ColNum+1,labelcol,tunit,tform
+                       ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
+   } else {
+     long repeatlng;
+     fits_get_acolparms(GetFitsPtr(),ColNum+1,labelcol,&repeatlng,tunit,tform
+                       ,&tscale,&tzero,NULL,tdisp,&sta);
+     repeat = repeatlng;
+   }
+   if(rc) {
+     FitsOpenFile::printerror(sta);
+     throw RangeCheckError("FitsABTColRd1F::Init: Error getting the column caracteristics\n");
+   }
+   ColLabel.push_back(labelcol);
+   ColTUnit.push_back(tunit);
+   ColTForm.push_back(tform);
+   // fill the default buffer limits at init
+   LineDeb.push_back(-1);
+   LineFin.push_back(-1);
+   // some debug print if requested
+   if(DbgLevel)
+     cout<<"FitsABTColRd1F::Init Num="<<ColNum<<" Label="<<ColLabel[ColNum]
+         <<" TypeCode="<<ColTypeCode[ColNum]<<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]<<endl;
+   if(DbgLevel>1)
+     cout<<"      (repeat="<<repeat<<",tscale="<<tscale<<",tzero="<<tzero
+         <<",tdisp="<<tdisp<<")"<<endl;
+ }   // ***** ColNum
+
+ // Set the buffer for reading
+ ChangeBuffer(blen,bsens);
+
+}
+
+/*! Destructor. */
+FitsABTColRd1F::~FitsABTColRd1F()
+{
+ Delete();
+}
+
+/*! Delete called by the destructor */
+void FitsABTColRd1F::Delete(void)
+{
+  if(NBcol>0  && Buffer!=NULL) {
+    for(int ColNum=0; ColNum<NBcol; ColNum++)
+      if(Buffer[ColNum]!=NULL) delete [] Buffer[ColNum];
+    delete [] Buffer; Buffer=NULL;
+  }
+ LineDeb.resize(0); LineFin.resize(0);
+ //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
+}
+
+//////////////////////////////////////////////////////////////
+/*! Change the buffer caracteristiques (see creator) */
+void FitsABTColRd1F::ChangeBuffer(long blen,long bsens)
+{
+ long oldnbuffer = NBuffer;
+
+ // Compute buffer caracteristics
+ BuffLen = (blen<=0)? 1: blen;
+ BuffSens = bsens;
+ NBuffer = BuffLen;
+ if(bsens==0 && NBuffer%2==0) NBuffer++;
+
+ // De-allocate if necessary
+ if(Buffer!=NULL) {
+   // On des-alloue si pas assez de place
+   // ou si l'ancienne place est beaucoup trop grande (>25%)
+   if(oldnbuffer<NBuffer || (oldnbuffer>NBuffer+long(0.25*NBuffer)) ) {
+     for(int ColNum=0; ColNum<NBcol; ColNum++) if(Buffer[ColNum]!=NULL) delete [] Buffer[ColNum];
+     if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
+   }
+ }
+
+ // Re-allocate
+ if(Buffer==NULL) {
+   Buffer = new double*[NBcol];
+   for(int ColNum=0; ColNum<NBcol; ColNum++) Buffer[ColNum] = new double[NBuffer];
+ }
+
+ // Tell program that nothing is into buffer
+ for(int ColNum=0; ColNum<NBcol; ColNum++) LineDeb[ColNum] = LineFin[ColNum] = -1;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsABTColRd1F::ReadKey(const char *keyname)
+{
+ return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsABTColRd1F::ReadKeyL(const char *keyname)
+{
+ return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into long long
+  \param keyname : name of the key
+  \return value into long long
+*/
+LONGLONG FitsABTColRd1F::ReadKeyLL(const char *keyname)
+{
+ return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
+}
+
+/*!
+  Read a fitsheader key into string
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsABTColRd1F::ReadKeyS(const char *keyname)
+{
+ return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
+}
+
+/////////////////////////////////////////////////
+int FitsABTColRd1F::GetColNum(const char *colname)
+ // Get column number from column name
+{
+ if(strlen(colname)<1 || NBcol<1) return -1;
+ string slab(colname);
+ for(int ColNum=0;ColNum<NBcol;ColNum++)
+   if(slab == ColLabel[ColNum]) return ColNum;
+ return -1;
+}
+
+/////////////////////////////////////////////////
+/*!
+  Read row "n" of column "ColNum" and return the value into a double
+  \warning be carefull for the range: row = [0,NRows[
+  \return value in double
+  \param n : number of the row to be read.
+  \verbatim
+  usebuffer == true  : use read optimisation with bufferisation
+            == false : no optimisation with bufferisation
+                       just read one value
+  \endverbatim
+*/
+double FitsABTColRd1F::Read(int ColNum,LONGLONG n,bool usebuffer)
+// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
+// Attention: colnum  [0,NBcol[ , cfistio veut [1,NBcol]
+{
+ int sta=0;
+ if(ColNum<0 || ColNum>=NBcol)
+   throw RangeCheckError("FitsABTColRd1F::Read try to read outside column range\n");
+ if(n<0 || n>=NBline)
+   throw RangeCheckError("FitsABTColRd1F::Read try to read outside line range\n");
+
+ // Pas de bufferisation, on lit betement
+ if(NBuffer==1 || !usebuffer) {
+   double val;
+   fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     throw NotAvailableOperation("FitsABTColRd1F::Read: Error Reading Fits file\n");
+   }
+   // On ne remplit Buffer[ColNum][0] que si on a choisit
+   // un mode de lecture non bufferise (n==1) DES LE DEBUT.
+   // Si on a initialement choisit un mode bufferise (avec n>1),
+   // Buffer contient les valeurs chargees auparavent.
+   // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
+   // car on perd l'info de ces valeurs.
+   if(NBuffer==1) {Buffer[ColNum][0]=val; LineDeb[ColNum]=LineFin[ColNum]=n;}
+   return val;
+ }
+
+ // Gestion avec bufferisation
+ if(!Buffer)
+   throw RangeCheckError("FitsABTColRd1F::Read: Buffer not allocated\n");
+ if(n<LineDeb[ColNum] || n>LineFin[ColNum]) {
+   LONGLONG row1,row2,nrow;
+   if(BuffSens>0) { // Cas remplissage forward
+     row1 = n+1;
+     row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
+   } else if(BuffSens<0) { // Cas remplissage backward
+     row2 = n+1;
+     row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
+   } else { // Cas remplissage centre
+     row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
+     row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
+   }
+   nrow = row2 - row1 + 1;
+   LineDeb[ColNum] = row1-1; LineFin[ColNum] = row2-1;
+   //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
+   //    <<" LineDeb,Fin="<<LineDeb[ColNum]<<","<<LineFin[ColNum]<<endl;
+   fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer[ColNum],NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta);
+     LineDeb[ColNum] = LineFin[ColNum] = -1;
+     throw NotAvailableOperation("FitsABTColRd1F::Read: Error Reading Fits file\n");
+   }
+ }
+
+ long ibuf = n-LineDeb[ColNum];
+ return Buffer[ColNum][ibuf];
+}
+
+
+/*! Print on stream os */
+void FitsABTColRd1F::Print(ostream& os,int lp) const
+{
+ os<<"FitsABTColRd1F:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
+   <<" ncols="<<NBcol<<" nrows="<<NBline;
+ os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"<<endl;
+ if(lp>0 && NBcol>0) {
+   for(int ColNum=0;ColNum<NBcol;ColNum++) {
+     os<<"..Col="<<ColNum<<" Label="<<ColLabel[ColNum]<<" TypeCode="<<ColTypeCode[ColNum]
+       <<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]
+       <<endl;
+   }
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+/*!
+  Constructor.
+  Same as before but the column is identified by its column number
+  \param colnum : number of the column to be read
+  \warning col = [0,ncol[
+*/
+FitsABTColRead1F::FitsABTColRead1F(string fname,int ihdu,long blen,long bsens,int lp)
+: FitsABTColRd1F(new FitsOpenFile(fname),ihdu,blen,bsens,lp)
+{
+}
+
+/*! Constructor. see below */
+FitsABTColRead1F::FitsABTColRead1F(const char * cfname,int ihdu,long blen,long bsens,int lp)
+: FitsABTColRd1F(new FitsOpenFile(cfname),ihdu,blen,bsens,lp)
+{
+}
+
+/*! Destructor. */
+FitsABTColRead1F::~FitsABTColRead1F()
+{
+ Delete(); // ?? inutile ??
+ // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
+ if(FitsOF!=NULL) delete FitsOF;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
 //! Class for reading a 2D image from a FITS file
 
