Index: /trunk/SophyaExt/FitsIOServer/fboloread.cc
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fboloread.cc	(revision 1661)
+++ /trunk/SophyaExt/FitsIOServer/fboloread.cc	(revision 1661)
@@ -0,0 +1,245 @@
+/* Lecteur Fits de bolometre */
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fboloread.h"
+
+#define _NCOL_BOLO_MIN_ 5
+
+/*!
+  \class SOPHYA::FitsBoloRead
+  \ingroup FitsIOServer
+  Class for defining a bolometer by connecting columns out FITS files
+  \verbatim
+  -- Exemple:
+  FitsBoloRead fbr(blen,bsens);
+  fbr.SetDebug(2);
+
+  fbr.SetBolo("bolomuv","bolo.fits",0);
+  fbr.SetFlag("flag");
+  fbr.SetSNum("samplenum");
+  fbr.SetAlpha("alpha","alpha.fits",0);
+  fbr.SetDelta("delta");
+  int col1 = fbr.AddCol("altitude","other_file.fits");
+  fbr.Print(2);
+  cout<<"NRows= "<<fbr.GetNbLine()<<endl;
+
+  cout<<"Reading element by elements"<<endl;
+  for(long i=0; i<fbr.GetNbLine(); i++) {
+    double a = fbr.GetAlpha(i);
+    double d = fbr.GetDelta(i);
+    double b = fbr.GetBolo(i);
+    double s = fbr.GetSNum(i);
+    double f = fbr.GetFlag(i);
+    double c1 = fbr.GetCol(col1,i);
+    cout<<i<<" s="<<(long long)s<<" b="<<b<<" f="<<f
+        <<" a="<<a<<" d="<<d<<" c1="c1<<endl;
+  }
+
+  cout<<"Reading with vectors"<<endl;
+  TVector<double> Va,Vd,Vb,Vf;
+  TVector<float> Vc1;
+  TVector<int_4> Vs;
+  for(long i=0, istep=1000; i<fbr.GetNbLine(); i+=istep) {
+    long i2=i+istep-1; if(i2>=fbr.GetNbLine()) i2=fbr.GetNbLine()-1;
+    fbr.GetSNum(i,i2,Vs);
+    fbr.GetBolo(i,i2,Vb);
+    fbr.GetFlag(i,i2,Vf);
+    fbr.GetAlpha(i,i2,Va);
+    fbr.GetDelta(i,i2,Vd);
+    fbr.GetCol(col1,i,i2,Vc1);
+  }
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor. Define the structure of the bolometer columns connector.
+  \param blen : read buffer length
+  \param bsens : buffer reading direction
+  \verbatim
+  - bsens>0    read forward
+    bsens<0    read backward
+    bsens==0   read centered
+  \endverbatim
+*/
+FitsBoloRead::FitsBoloRead(long blen,long bsens)
+  : NBline(0), DbgLevel(0), BuffLen(blen), BuffSens(bsens)
+{
+  for(int i=0;i<_NCOL_BOLO_MIN_;i++) {
+    mFName.push_back("");
+    mLabel.push_back("");
+    mHDU.push_back(0);
+    mFABT.push_back(NULL);
+  }
+}
+
+/*! Destructor */
+FitsBoloRead::~FitsBoloRead(void)
+{
+ for(int i=0; i<(int)mFABT.size(); i++)
+   if(mFABT[i]!=NULL) {delete mFABT[i]; mFABT[i]=NULL;}
+ // NBline=0; mFABT.resize(_NCOL_BOLO_MIN_);
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+ Add the column number "col" to the bolometer connector.
+ Protected method. Do not use directly but read the doc.
+ \param col : number of the column to be added
+ \param label : label of the column
+ \param fname : FITS file name containing the column
+ \param ihdu : FITS HDU containing the column
+ \verbatim
+ - col<0     : add a new column
+   col<size  : fill a new column
+   col>=size : throw exception
+ - The method also set the number of rows of the Bolometer connector
+   as the smallest number of rows of the connected columns.
+   That could be changed by using the SetNbLine() method.
+ -----------------------------------------------------------------
+ It is very boring to define all the fits file names and hdu for
+   the predefined TOI SNum,Bolo,Flag,Alpha,Delta as some of them
+   are in the same FITS file (and HDU).
+ The connector pre-defined a logic as follow:
+ ... if fname_Bolo=="" try fname_SNum
+ ... if fname_SNum=="" try fname_Bolo
+ ... if fname_Flag=="" try fname_Bolo first
+ ...                       fname_SNum second.
+ ... if fname_Alpha=="" try fname_Delta first
+ ...                        fname_Bolo second
+ ...                        fname_SNum third
+ ... if fname_Delta=="" try fname_Alpha first
+ ...                        fname_Bolo second
+ ...                        fname_SNum third
+ Of course, the decision differs depending on the order
+   of calling the addcol() method.
+ -----------------------------------------------------------------
+ \endverbatim
+ \warning ihdu[1,nhdu], col=[0,nrow-1]
+ \return The number of the column added in the FitsBoloRead connector.
+*/
+int FitsBoloRead::addcol(int col,const char *label,const char* fname,int ihdu)
+{
+ if(col>=(int)mFABT.size()) // Not an existing column
+   throw ParmError("FitsBoloRead::addcol: column number not existing\n");
+
+ if(col>=0) {  // Already filled column
+   if(mFABT[col]!=NULL) delete mFABT[col];
+ } else {      // Prepare for new column
+   col=mFABT.size();
+   mFName.push_back("");
+   mLabel.push_back("");
+   mHDU.push_back(0);
+   mFABT.push_back(NULL);
+ }
+
+ if(fname) mFName[col] = fname; else mFName[col] = "";
+ mLabel[col] = label;
+ mHDU[col]   = ihdu;
+ // Try to guess the fname and ihdu if not defined
+ Gess_If_Not_Define(col);
+
+ mFABT[col] =
+   new FitsABTColRead(mFName[col].c_str(),mLabel[col].c_str()
+                     ,mHDU[col],BuffLen,BuffSens,(int)DbgLevel);
+
+ // Set the number of rows as the smallest of for connected columns
+ long nrows = mFABT[col]->GetNbLine();
+ if(NBline==0) NBline = nrows;
+ else if(nrows<NBline) NBline = nrows;
+
+ return col;
+}
+
+/*!
+  Guess what are the File name and HDU if they are not explicitly defined.
+  (See addcol() doc)
+*/
+void FitsBoloRead::Gess_If_Not_Define(int col)
+{
+ if(col<0 || col>=_NCOL_BOLO_MIN_) return; // Pas une colonne predefinie
+ if(mFName[col].size()>0) return; // definition explicite
+
+ if(col==ColSNum) {            // Cas du Sample Number
+   if(mFName[ColBolo].size()>0)
+     {mFName[col]=mFName[ColBolo]; mHDU[col]=mHDU[ColBolo]; return;}
+
+ } else if(col==ColBolo) {     // Cas du Bolo
+   if(mFName[ColSNum].size()>0)
+     {mFName[col]=mFName[ColSNum]; mHDU[col]=mHDU[ColSNum]; return;}
+
+ } else if(col==ColFlag) {     // Cas du Flag
+   if(mFName[ColBolo].size()>0)
+     {mFName[col]=mFName[ColBolo]; mHDU[col]=mHDU[ColBolo]; return;}
+   if(mFName[ColSNum].size()>0)
+     {mFName[col]=mFName[ColSNum]; mHDU[col]=mHDU[ColSNum]; return;}
+
+ } else if(col==ColAlpha) {    // Cas du Alpha
+   if(mFName[ColDelta].size()>0)
+     {mFName[col]=mFName[ColDelta]; mHDU[col]=mHDU[ColDelta]; return;}
+   if(mFName[ColBolo].size()>0)
+     {mFName[col]=mFName[ColBolo]; mHDU[col]=mHDU[ColBolo]; return;}
+   if(mFName[ColSNum].size()>0)
+     {mFName[col]=mFName[ColSNum]; mHDU[col]=mHDU[ColSNum]; return;}
+
+ } else if(col==ColDelta) {    // Cas du Delta
+   if(mFName[ColAlpha].size()>0)
+     {mFName[col]=mFName[ColAlpha]; mHDU[col]=mHDU[ColAlpha]; return;}
+   if(mFName[ColBolo].size()>0)
+     {mFName[col]=mFName[ColBolo]; mHDU[col]=mHDU[ColBolo]; return;}
+   if(mFName[ColSNum].size()>0)
+     {mFName[col]=mFName[ColSNum]; mHDU[col]=mHDU[ColSNum]; return;}
+ }
+}
+
+//////////////////////////////////////////////////////////////
+/*! Set the number of rows for that class, choosing column "col"
+  \param col : number of the column giving the number of rows
+  \verbatim
+  col : <0         set nrows to the smallest of all connected columns
+  col : [0,ncol-1] set nrows to the number of rows of column "col"
+  col : >=ncol     trow exception
+  \endverbatim
+  \warning By default, the number of rows is set to the smallest of all connected columns
+*/
+void FitsBoloRead::SetNbLine(int col)
+{
+  if(col>=(int)mFABT.size())  // Bad column number
+   throw ParmError("FitsBoloRead::SetNbLine: bad column number\n");
+
+ if(col>=0) {  // existing column, return its NbLine
+   if(mFABT[col]==NULL)
+     throw NullPtrError("FitsBoloRead::SetNbLine: column not connected\n");
+   NBline = mFABT[col]->GetNbLine();
+ }
+
+ // take the smallest NbLine for all columns
+ NBline = 0;
+ for(col=0; col<(int)mFABT.size(); col++) {
+   if(mFABT[col]==NULL) continue;
+   long nbl = mFABT[col]->GetNbLine();
+   if(nbl==0) continue;
+   if(NBline==0 || nbl<NBline) NBline = nbl;
+ }
+}
+
+//////////////////////////////////////////////////////////////
+/*! Print */
+void FitsBoloRead::Print(ostream& os,int lp) const
+{
+ os<<"FitsBoloRead::Print: NBline="<<NBline<<" NCol="<<GetNbCol()<<endl;
+ for(int i=0; i<(int)mFABT.size(); i++) {
+   if(mFABT[i]==NULL) {
+      cout<<"...Col "<<i<<" not connected"<<endl;
+      continue;
+   } else {
+     cout<<"--> Col "<<i<<" label="<<mLabel[i]<<" hdu="<<mHDU[i]
+         <<"        FName="<<mFName[i]<<endl;
+     if(lp>0) mFABT[i]->Print(os,lp);
+   }
+ }
+}
+
+#undef _NCOL_BOLO_MIN_
Index: /trunk/SophyaExt/FitsIOServer/fboloread.h
===================================================================
--- /trunk/SophyaExt/FitsIOServer/fboloread.h	(revision 1661)
+++ /trunk/SophyaExt/FitsIOServer/fboloread.h	(revision 1661)
@@ -0,0 +1,188 @@
+/* Interface Fits pour bolometre    cmv 29/09/2001 */
+#ifndef FBOLOREAD_H_SEEN
+#define FBOLOREAD_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "tvector.h"
+#include "fabtcolread.h"
+
+#include <vector>
+
+namespace SOPHYA {
+
+//! Class for defining a bolometer by connecting columns out FITS files
+class FitsBoloRead : public AnyDataObj {
+public:
+  enum {ColSNum=0, ColBolo=1, ColFlag=2, ColAlpha=3, ColDelta=4};
+
+  FitsBoloRead(long blen=100,long bsens=1);
+  virtual ~FitsBoloRead();
+
+  //! Define the Alpha column connection (see addcol).
+  inline int SetAlpha(const char *label,const char* fname="",int ihdu=0)
+              {return addcol(ColAlpha,label,fname,ihdu);}
+  //! Define the Delta column connection (see addcol).
+  inline int SetDelta(const char *label,const char* fname="",int ihdu=0)
+              {return addcol(ColDelta,label,fname,ihdu);}
+  //! Define the Bolo column connection (see addcol).
+  inline int SetBolo(const char *label,const char* fname="",int ihdu=0)
+              {return addcol(ColBolo,label,fname,ihdu);}
+  //! Define the Flag column connection (see addcol).
+  inline int SetFlag(const char *label,const char* fname="",int ihdu=0)
+              {return addcol(ColFlag,label,fname,ihdu);}
+  //! Define the Sample Number column connection (see addcol).
+  inline int SetSNum(const char *label,const char* fname="",int ihdu=0)
+              {return addcol(ColSNum,label,fname,ihdu);}
+  //! Add a new column connection (see addcol).
+  inline int AddCol(const char *label,const char* fname,int ihdu=0)
+              {return addcol(-1,label,fname,ihdu);}
+
+  //! return Alpha value for row "n" into double
+  inline double GetAlpha(long n,bool usebuffer=true)
+                {return GetCol(ColAlpha,n,usebuffer);}
+  //! return Delta value for row "n" into double
+  inline double GetDelta(long n,bool usebuffer=true)
+                {return GetCol(ColDelta,n,usebuffer);}
+  //! return Bolo value for row "n" into double
+  inline double GetBolo(long n,bool usebuffer=true)
+                {return GetCol(ColBolo,n,usebuffer);}
+  //! return Flag value for row "n" into double
+  inline double GetFlag(long n,bool usebuffer=true)
+         {if(!IsFlag()) return 0.; return GetCol(ColFlag,n,usebuffer);}
+  //! return SNum value for row "n" into double
+  inline double GetSNum(long n,bool usebuffer=true)
+                {return GetCol(ColSNum,n,usebuffer);}
+  //! return column "col" value for row "n" into double
+  inline double GetCol(int col,long n,bool usebuffer=true) {
+    if(col<0 || col>=(int)mFABT.size())
+      throw ParmError("FitsBoloRead::GetCol: bad column number\n");
+    if(mFABT[col]==NULL)
+      throw NullPtrError("FitsBoloRead::GetCol: column not connected\n");
+    return mFABT[col]->Read(n,usebuffer);
+  }
+
+  //! return Alpha values for rows [n1,n2] into TVector
+  inline long GetAlpha(long n1,long n2,TVector<double>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+  inline long GetAlpha(long n1,long n2,TVector<float>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+  inline long GetAlpha(long n1,long n2,TVector<int_4>& data)
+              {return GetCol(ColAlpha,n1,n2,data);}
+
+  //! return Delta values for rows [n1,n2] into TVector
+  inline long GetDelta(long n1,long n2,TVector<double>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+  inline long GetDelta(long n1,long n2,TVector<float>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+  inline long GetDelta(long n1,long n2,TVector<int_4>& data)
+              {return GetCol(ColDelta,n1,n2,data);}
+
+  //! return Bolo values for rows [n1,n2] into TVector
+  inline long GetBolo(long n1,long n2,TVector<double>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+  inline long GetBolo(long n1,long n2,TVector<float>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+  inline long GetBolo(long n1,long n2,TVector<int_4>& data)
+              {return GetCol(ColBolo,n1,n2,data);}
+
+  //! return Flag values for rows [n1,n2] into TVector
+  inline long GetFlag(long n1,long n2,TVector<double>& data)
+              {if(!IsFlag()) return 0; return GetCol(ColFlag,n1,n2,data);}
+  inline long GetFlag(long n1,long n2,TVector<float>& data)
+              {if(!IsFlag()) return 0; return GetCol(ColFlag,n1,n2,data);}
+  inline long GetFlag(long n1,long n2,TVector<int_4>& data)
+              {if(!IsFlag()) return 0; return GetCol(ColFlag,n1,n2,data);}
+
+  //! return Sample Number values for rows [n1,n2] into TVector
+  inline long GetSNum(long n1,long n2,TVector<double>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+  inline long GetSNum(long n1,long n2,TVector<float>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+  inline long GetSNum(long n1,long n2,TVector<int_4>& data)
+              {return GetCol(ColSNum,n1,n2,data);}
+
+  //! return column "col" values for rows [n1,n2] into TVector
+  inline long GetCol(int col,long n1,long n2,TVector<double>& data) {
+    if(col<0 || col>=(int)mFABT.size()) return 0; if(mFABT[col]==NULL) return 0;
+    return mFABT[col]->Read(n1,n2,data);
+  }
+  inline long GetCol(int col,long n1,long n2,TVector<float>& data) {
+    if(col<0 || col>=(int)mFABT.size()) return 0; if(mFABT[col]==NULL) return 0;
+    return mFABT[col]->Read(n1,n2,data);
+  }
+  inline long GetCol(int col,long n1,long n2,TVector<int_4>& data) {
+    if(col<0 || col>=(int)mFABT.size()) return 0; if(mFABT[col]==NULL) return 0;
+    return mFABT[col]->Read(n1,n2,data);
+  }
+
+  //! return the value of the first sampleNum
+  inline double ReadFirstSNum(void) {return GetSNum(0,false);}
+  //! return the value of the last sampleNum
+  inline double ReadLastSNum(void)  {return GetSNum(NBline-1,false);}
+
+  //! Is Alpha connected ?
+  inline bool IsAlpha(void)  {return IsCol(ColAlpha);}
+  //! Is Delta connected ?
+  inline bool IsDelta(void)  {return IsCol(ColDelta);}
+  //! Is Bolo connected ?
+  inline bool IsBolo(void)   {return IsCol(ColBolo);}
+  //! Is Flag connected ?
+  inline bool IsFlag(void)   {return IsCol(ColFlag);}
+  //! Is SNum connected ?
+  inline bool IsSNum(void)   {return IsCol(ColSNum);}
+  //! Is column col connected ?
+  inline bool IsCol(int col) {if(mFABT[col]) return true; return false;}
+
+  //! Set debug level
+  inline void SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+  //! Set the number of rows for that class choosing column "col"
+  void SetNbLine(int col=-1);
+  //! Get the number of rows to be read
+  inline long GetNbLine(void) const {return NBline;}
+  //! Get the number of columns in the FITS HDU to be read
+  inline int  GetNbCol(void) const {return mFABT.size();}
+  //! Get the read requested buffer length
+  inline long GetBLen(void) const {return BuffLen;}
+  //! Get the read buffer direction
+  inline long GetBSens(void) const {return BuffSens;}
+  //! Print to os
+  virtual void Print(ostream& os,int lp=1) const;
+  //! Print to stdout
+  inline  void Print(int lp=1) const {Print(cout,lp);}
+
+  //! Get the FitsABTColRead pointer for the Alpha
+  inline FitsABTColRead* GetAlphaReader(void) {return GetColReader(ColAlpha);}
+  //! Get the FitsABTColRead pointer for the Delta
+  inline FitsABTColRead* GetDeltaReader(void) {return GetColReader(ColDelta);}
+  //! Get the FitsABTColRead pointer for the Bolo
+  inline FitsABTColRead* GetBoloReader(void) {return GetColReader(ColBolo);}
+  //! Get the FitsABTColRead pointer for the Flag
+  inline FitsABTColRead* GetFlagReader(void) {return GetColReader(ColFlag);}
+  //! Get the FitsABTColRead pointer for the SNum
+  inline FitsABTColRead* GetSNumReader(void) {return GetColReader(ColSNum);}
+  //! Get the FitsABTColRead pointer for the column "col"
+  inline FitsABTColRead* GetColReader(int col)
+    {if(col<0 || col>=(int)mFABT.size()) return NULL; return mFABT[col];}
+
+protected:
+  //! Protected method. Do not use directly but read the doc.
+  int addcol(int col,const char *label,const char* fname,int ihdu);
+  void Gess_If_Not_Define(int col);
+
+  long NBline;
+  unsigned short DbgLevel;
+  long BuffLen, BuffSens;
+
+  vector<string> mFName;
+  vector<string> mLabel;
+  vector<int> mHDU;
+  vector<FitsABTColRead *> mFABT;
+};
+
+} // namespace SOPHYA
+#endif    /* FBOLOREAD_H_SEEN */
