Index: trunk/SophyaExt/FitsIOServer/fabtwriter.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2450)
+++ trunk/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2453)
@@ -6,4 +6,189 @@
 #include "fabtwriter.h"
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsWriter
+  \ingroup FitsIOServer
+  Class for writing into a FITS file (DO NOT USE)
+*/
+
+/*! Constructor  (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,int lp)
+{
+  cr_or_upd_fits(cfname,false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,bool update,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),update,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,bool update,int lp)
+{
+  cr_or_upd_fits(cfname,update,lp);
+}
+
+/*! See FitsWriter() */
+void FitsWriter::cr_or_upd_fits(const char *cfname,bool update,int lp)
+{
+ FitsPtr = NULL;
+ HduType = 0;
+ SetDebug(lp);
+ FitsFN = cfname;
+ NOverFlow = 0;
+ Update = update;
+ // Init key structure
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ StringKey.resize(0);
+
+ if(DbgLevel)
+   cout<<"FitsWriter::cr_or_upd_fits FitsFN="<<FitsFN<<endl;
+
+ if(FitsFN.size() <= 0 )
+   throw ParmError("FitsWriter::cr_or_upd_fits: Fits file name error\n");
+
+ // create or update FITS file
+ int sta=0;
+ if(Update) {
+   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READWRITE,&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error opening Fits file for update\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: fits file has been opened for update"<<endl;
+ } else {
+   if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating new Fits file\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: a new fits file has been created"<<endl;
+ }
+
+ // create d'un Primary HDU
+ //long naxes[1] = {0};
+ //if(fits_create_img(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
+ //  printerror(sta);
+ //  throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating Primary extension\n");
+ //}
+}
+
+/*! Destructor */
+FitsWriter::~FitsWriter()
+{
+ int sta = 0;
+ writekeys();
+ if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+ FitsPtr = NULL;
+}
+
+/*! Flush the FitsIO buffer to set good Fits file in case of problems */
+void FitsWriter::Flush(void)
+{
+ if(FitsPtr==NULL) return;
+ int sta = 0;
+ if(fits_flush_file(FitsPtr,&sta)) printerror(sta);
+}
+
+
+/*! Write a double value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,double val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyDouble k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ DoubleKey.push_back(k);
+}
+
+/*! Write a long value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,long val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyLong k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ LongKey.push_back(k);
+}
+
+/*! Write a string value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,string val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyString k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ StringKey.push_back(k);
+}
+
+void FitsWriter::writekeys(void)
+// Ecriture effective des clefs
+{
+ if(FitsPtr==NULL) return;
+ int sta=0;
+ if(DoubleKey.size()>0)
+   for(unsigned int i=0;i<DoubleKey.size();i++) {
+     char* key = const_cast<char*>(DoubleKey[i].keyname.c_str());
+     char* com = const_cast<char*>(DoubleKey[i].comment.c_str());
+     double val = DoubleKey[i].val;
+     if(fits_update_key(FitsPtr,TDOUBLE,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(LongKey.size()>0)
+   for(unsigned int i=0;i<LongKey.size();i++) {
+     char* key = const_cast<char*>(LongKey[i].keyname.c_str());
+     char* com = const_cast<char*>(LongKey[i].comment.c_str());
+     long val = LongKey[i].val;
+     if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(StringKey.size()>0)
+   for(unsigned int i=0;i<StringKey.size();i++) {
+     char* key = const_cast<char*>(StringKey[i].keyname.c_str());
+     char* com = const_cast<char*>(StringKey[i].comment.c_str());
+     char* val = const_cast<char*>(StringKey[i].val.c_str());
+     if(fits_update_key(FitsPtr,TSTRING,key,val,com,&sta))
+       printerror(sta);
+   }
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ StringKey.resize(0);
+}
+
+void FitsWriter::printerrorwrite(const char* type,int col,long row,int sta)
+{
+ if(sta==NUM_OVERFLOW) {NOverFlow++; return;}
+ printerror(sta);
+ char str[256];
+ sprintf(str,"FitsWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d"
+        ,type,col,row,sta);
+ throw NotAvailableOperation(str);
+}
+
+void FitsWriter::printerror(int sta) const
+{
+ int stat = sta;
+ fits_report_error(stdout,stat);
+ fflush(stdout);
+ return;
+}
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
 /*!
   \class SOPHYA::FitsABTWriter
@@ -117,6 +302,11 @@
 */
 FitsABTWriter::FitsABTWriter(string fname,int hdutype,int lp)
-{
-  cr_or_upd_fits(fname.c_str(),false,hdutype,lp);
+: FitsWriter(fname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -128,6 +318,11 @@
 */
 FitsABTWriter::FitsABTWriter(const char* cfname,int hdutype,int lp)
-{
-  cr_or_upd_fits(cfname,false,hdutype,lp);
+: FitsWriter(cfname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -140,6 +335,11 @@
 */
 FitsABTWriter::FitsABTWriter(string fname,bool update,int hdutype,int lp)
-{
-  cr_or_upd_fits(fname.c_str(),update,hdutype,lp);
+: FitsWriter(fname,update,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -152,52 +352,11 @@
 */
 FitsABTWriter::FitsABTWriter(const char* cfname,bool update,int hdutype,int lp)
-{
-  cr_or_upd_fits(cfname,update,hdutype,lp);
-}
-
-/*! See FitsABTWriter() */
-void FitsABTWriter::cr_or_upd_fits(const char *cfname,bool update,int hdutype,int lp)
+: FitsWriter(cfname,update,lp)
 {
  FirstTime = true;
- FitsPtr = NULL;
  HduType = hdutype;
- SetDebug(lp);
- FitsFN = cfname;
- NOverFlow = 0;
- Update = update;
-
- if(DbgLevel)
-   cout<<"FitsABTWriter::cr_or_upd_fits FitsFN="<<FitsFN
-       <<" HduType="<<HduType<<endl;
-
- if(FitsFN.size() <= 0 )
-   throw ParmError("FitsABTWriter::cr_or_upd_fits: Fits file name error\n");
-
  if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
-   throw TypeMismatchExc("FitsABTWriter::cr_or_upd_fits: Only BINARY or ASCII table permitted\n");
-
- // create or update FITS file
- int sta=0;
- if(Update) {
-   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READWRITE,&sta)) {
-     printerror(sta);
-     throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error opening Fits file for update\n");
-   }
-   if(DbgLevel) cout<<"FitsABTWriter::cr_or_upd_fits: fits file has been opened for update"<<endl;
- } else {
-   if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
-     printerror(sta);
-     throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error creating new Fits file\n");
-   }
-   if(DbgLevel) cout<<"FitsABTWriter::cr_or_upd_fits: a new fits file has been created"<<endl;
- }
-
- // create d'un Primary HDU
- //long naxes[1] = {0};
- //if(fits_create_img(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
- //  printerror(sta);
- //  throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error creating Primary extension\n");
- //}
-
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -205,83 +364,4 @@
 FitsABTWriter::~FitsABTWriter()
 {
- int sta = 0;
- writekeys();
- if(fits_close_file(FitsPtr,&sta)) printerror(sta);
- FitsPtr = NULL;
-}
-
-/*! Flush the FitsIO buffer to set good Fits file in case of problems */
-void FitsABTWriter::Flush(void)
-{
- if(FitsPtr==NULL) return;
- int sta = 0;
- if(fits_flush_file(FitsPtr,&sta)) printerror(sta);
-}
-
-/*! Write a double value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,double val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyDouble k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- DoubleKey.push_back(k);
-}
-
-/*! Write a long value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,long val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyLong k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- LongKey.push_back(k);
-}
-
-/*! Write a string value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,string val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyString k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- StringKey.push_back(k);
-}
-
-void FitsABTWriter::writekeys(void)
-// Ecriture effective des clefs
-{
- if(FitsPtr==NULL) return;
- int sta=0;
- if(DoubleKey.size()>0)
-   for(unsigned int i=0;i<DoubleKey.size();i++) {
-     char* key = const_cast<char*>(DoubleKey[i].keyname.c_str());
-     char* com = const_cast<char*>(DoubleKey[i].comment.c_str());
-     double val = DoubleKey[i].val;
-     if(fits_update_key(FitsPtr,TDOUBLE,key,&val,com,&sta))
-       printerror(sta);
-   }
- if(LongKey.size()>0)
-   for(unsigned int i=0;i<LongKey.size();i++) {
-     char* key = const_cast<char*>(LongKey[i].keyname.c_str());
-     char* com = const_cast<char*>(LongKey[i].comment.c_str());
-     long val = LongKey[i].val;
-     if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta))
-       printerror(sta);
-   }
- if(StringKey.size()>0)
-   for(unsigned int i=0;i<StringKey.size();i++) {
-     char* key = const_cast<char*>(StringKey[i].keyname.c_str());
-     char* com = const_cast<char*>(StringKey[i].comment.c_str());
-     char* val = const_cast<char*>(StringKey[i].val.c_str());
-     if(fits_update_key(FitsPtr,TSTRING,key,val,com,&sta))
-       printerror(sta);
-   }
- DoubleKey.resize(0);
- LongKey.resize(0);
- StringKey.resize(0);
 }
 
@@ -303,6 +383,6 @@
                          ,const char* tunit,int datatype)
 {
-  if(!FirstTime)
-    throw AllocationError("FitsABTWriter::addcol: table already created\n");
+ if(!FirstTime)
+   throw AllocationError("FitsABTWriter::addcol: table already created\n");
  
  // Gestion auto du tform pour les tables binaires avec le datatype (si non-definie)
@@ -402,7 +482,4 @@
  }
 
- // Append Fits key
- writekeys();
-
  // menage
  if(extname) delete [] extname;
@@ -591,24 +668,4 @@
 }
 
-//////////////////////////////////////////////////////////////
-void FitsABTWriter::printerrorwrite(const char* type,int col,long row,int sta)
-{
- if(sta==NUM_OVERFLOW) {NOverFlow++; return;}
- printerror(sta);
- char str[256];
- sprintf(str,"FitsABTWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d"
-        ,type,col,row,sta);
- throw NotAvailableOperation(str);
-}
-
-/////////////////////////////////////////////////
-void FitsABTWriter::printerror(int sta) const
-{
- int stat = sta;
- fits_report_error(stdout,stat);
- fflush(stdout);
- return;
-}
-
 /////////////////////////////////////////////////
 void FitsABTWriter::Print(ostream& os,int lp) const
@@ -621,2 +678,188 @@
     os<<i<<"... Label="<<Label[i]<<" TForm="<<TForm[i]<<" TUnit="<<TUnit[i]<<endl;
 }
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsImg2DWriter
+  \ingroup FitsIOServer
+  Class for writing an image into FITS file
+*/
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,int bitpix,int lp)
+: FitsWriter(fname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,int bitpix,int lp)
+: FitsWriter(cfname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,bool update,int bitpix,int lp)
+: FitsWriter(fname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,bool update,int bitpix,int lp)
+: FitsWriter(cfname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*! Destructor */
+FitsImg2DWriter::~FitsImg2DWriter()
+{
+}
+
+/*! Create the image. Done at the first write request. */
+void FitsImg2DWriter::createimg(void)
+{
+ if(!FirstTime)
+   throw NotAvailableOperation("FitsImg2DWriter::createimg: already created image\n");
+ if(Naxis[0]<=0 || Naxis[1]<=0)
+   throw ParmError("FitsImg2DWriter::createimg: bad Naxis 1 or 2 value\n");
+
+ int sta=0;
+ if(fits_create_img(FitsPtr,BitPix,2,Naxis,&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsImg2DWriter::createimg: Error creating image extension\n");
+ }
+
+ FirstTime = false;
+}
+
+/*!
+  Write an image to FITS file.
+  \warning TMatrix data(Naxis2,Naxis1)
+*/
+void FitsImg2DWriter::Write(TMatrix<uint_2>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ uint_2* arr = new uint_2[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TUSHORT,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<uint_2>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<int_4>& data)
+{
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ int_4* arr = new int_4[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,T,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<int_4>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<float>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ float* arr = new float[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TFLOAT,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<float>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<double>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ double* arr = new double[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TDOUBLE,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<double>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Print infos. */
+void FitsImg2DWriter::Print(ostream& os) const
+{
+os<<"FitsImg2DWriter::Print: FitsFN "<<FitsFN<<endl
+  <<"  HduType "<<HduType<<"  NOverFlow "<<NOverFlow<<"  BitPix "<<BitPix
+  <<"  Naxis1 "<<Naxis[0]<<"  Naxis2 "<<Naxis[1]<<endl;
+}
